mirror of
https://github.com/emo2007/block-accounting.git
synced 2025-01-18 15:36:27 +00:00
payout ready, but needs fixes
This commit is contained in:
parent
0a74e430b8
commit
958bf670ae
@ -34,7 +34,7 @@ export class GetTransactionCount {}
|
||||
|
||||
export class GetTransactionDto extends ConfirmTransactionDto {}
|
||||
|
||||
export class DepositMultiSigDto {
|
||||
export class DepositContractDto {
|
||||
@IsString()
|
||||
@ApiProperty()
|
||||
contractAddress: string;
|
||||
|
@ -1,4 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// 0x74f11486DB0FCAA2dCDE0aEB477e1F37fCAa510A
|
||||
|
||||
pragma solidity ^0.8.19;
|
||||
// The wallet owners can
|
||||
@ -18,6 +19,9 @@ contract MultiSigWallet {
|
||||
event ConfirmTransaction(address indexed owner, uint indexed txIndex);
|
||||
event RevokeConfirmation(address indexed owner, uint indexed txIndex);
|
||||
event ExecuteTransaction(address indexed owner, uint indexed txIndex);
|
||||
event ExecuteTransactionFailed(address indexed owner, uint indexed txIndex, string reason);
|
||||
event Payout(address indexed employee, uint salaryInETH);
|
||||
event PayoutFailed(address indexed employee, uint salaryInETH, string reason);
|
||||
|
||||
address[] public owners;
|
||||
|
||||
@ -111,20 +115,63 @@ contract MultiSigWallet {
|
||||
emit ConfirmTransaction(msg.sender, _txIndex);
|
||||
}
|
||||
|
||||
function executeTransaction(
|
||||
uint _txIndex
|
||||
) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) {
|
||||
function executeTransaction(uint _txIndex)
|
||||
public
|
||||
onlyOwner
|
||||
txExists(_txIndex)
|
||||
notExecuted(_txIndex)
|
||||
{
|
||||
Transaction storage transaction = transactions[_txIndex];
|
||||
require(
|
||||
transaction.numConfirmations >= numConfirmationsRequired,
|
||||
'cannot execute tx'
|
||||
"cannot execute tx"
|
||||
);
|
||||
|
||||
|
||||
(bool success, bytes memory returnData) = transaction.to.call{value: transaction.value}(transaction.data);
|
||||
if (success) {
|
||||
transaction.executed = true;
|
||||
(bool success, ) = transaction.to.call{value: transaction.value}(
|
||||
transaction.data
|
||||
);
|
||||
require(success, 'tx failed');
|
||||
emit ExecuteTransaction(msg.sender, _txIndex);
|
||||
if (returnData.length > 0) {
|
||||
emitEventFromReturnData(returnData);
|
||||
}
|
||||
} else {
|
||||
// Get the revert reason and emit it
|
||||
if (returnData.length > 0) {
|
||||
// The call reverted with a message
|
||||
assembly {
|
||||
let returndata_size := mload(returnData)
|
||||
revert(add(32, returnData), returndata_size)
|
||||
}
|
||||
} else {
|
||||
// The call reverted without a message
|
||||
emit ExecuteTransactionFailed(msg.sender, _txIndex, "Transaction failed without a reason");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitEventFromReturnData(bytes memory returnData) internal {
|
||||
// Decode the selector from returnData
|
||||
bytes4 selector;
|
||||
assembly {
|
||||
selector := mload(add(returnData, 32))
|
||||
}
|
||||
|
||||
// Match the selector to the known events
|
||||
if (selector == Payout.selector) {
|
||||
(address employee, uint salaryInETH) = abi.decode(slice(returnData, 4, returnData.length), (address, uint));
|
||||
emit Payout(employee, salaryInETH);
|
||||
} else if (selector == PayoutFailed.selector) {
|
||||
(address employee, uint salaryInETH, string memory reason) = abi.decode(slice(returnData, 4, returnData.length), (address, uint, string));
|
||||
emit PayoutFailed(employee, salaryInETH, reason);
|
||||
}
|
||||
}
|
||||
function slice(bytes memory data, uint start, uint length) internal pure returns (bytes memory) {
|
||||
bytes memory result = new bytes(length);
|
||||
for (uint i = 0; i < length; i++) {
|
||||
result[i] = data[start + i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function revokeConfirmation(
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// 0x2F9442900d067a3D37A1C2aE99462E055e32c741
|
||||
pragma solidity ^0.8.7;
|
||||
|
||||
import {AggregatorV3Interface} from '@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol';
|
||||
@ -8,7 +8,8 @@ contract Salaries {
|
||||
AggregatorV3Interface internal dataFeed;
|
||||
address public multisigWallet;
|
||||
mapping(address => uint) public salaries;
|
||||
|
||||
event Payout(address indexed employee, uint salaryInETH);
|
||||
event PayoutFailed(address indexed employee, uint salaryInETH, string reason);
|
||||
//0xF0d50568e3A7e8259E16663972b11910F89BD8e7
|
||||
constructor(address _multisigWallet, address _priceFeedAddress) {
|
||||
multisigWallet = _multisigWallet;
|
||||
@ -42,7 +43,7 @@ contract Salaries {
|
||||
salaries[employee] = salaryInUSDT;
|
||||
}
|
||||
|
||||
function payoutInETH(address employee) external onlyMultisig {
|
||||
function payoutInETH(address payable employee) external onlyMultisig {
|
||||
uint salaryInUSDT = salaries[employee];
|
||||
require(salaryInUSDT > 0, 'No salary set');
|
||||
|
||||
@ -58,8 +59,16 @@ contract Salaries {
|
||||
'Insufficient contract balance'
|
||||
);
|
||||
|
||||
salaries[employee] = 0; // Reset salary after payment
|
||||
payable(employee).transfer(salaryInETH);
|
||||
(bool success, ) = employee.call{value: salaryInETH}("");
|
||||
if (success) {
|
||||
emit Payout(employee, salaryInETH);
|
||||
} else {
|
||||
emit PayoutFailed(employee, salaryInETH, "Transfer failed");
|
||||
}
|
||||
}
|
||||
|
||||
function dummy() public pure returns (uint){
|
||||
return 1337;
|
||||
}
|
||||
|
||||
// Fallback to receive ETH
|
||||
|
@ -3,7 +3,7 @@ import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { MultiSigWalletService } from 'src/hardhat/modules/multi-sig/multi-sig.service';
|
||||
import {
|
||||
ConfirmTransactionDto,
|
||||
DepositMultiSigDto,
|
||||
DepositContractDto,
|
||||
ExecuteTransactionDto,
|
||||
GetTransactionDto,
|
||||
RevokeConfirmationDto,
|
||||
@ -59,7 +59,7 @@ export class MultiSigInteractController {
|
||||
}
|
||||
|
||||
@Post('deposit')
|
||||
async deposit(@Body() dto: DepositMultiSigDto) {
|
||||
async deposit(@Body() dto: DepositContractDto) {
|
||||
return this.multiSigWalletService.deposit(dto);
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,16 @@
|
||||
import { TransactionReceipt, ethers } from 'ethers';
|
||||
import { TransactionReceipt, ethers, parseEther } from 'ethers';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import * as hre from 'hardhat';
|
||||
import { BaseContractService } from '../base-contract.service';
|
||||
import { MultiSigWalletDto } from './multi-sig.dto';
|
||||
import {
|
||||
ConfirmTransactionDto,
|
||||
DepositMultiSigDto,
|
||||
DepositContractDto,
|
||||
ExecuteTransactionDto,
|
||||
GetTransactionDto,
|
||||
RevokeConfirmationDto,
|
||||
SubmitTransactionDto,
|
||||
} from 'src/contract-interact/dto/multi-sig.dto';
|
||||
import {
|
||||
ConfirmTransactionLogs,
|
||||
DepositLogs,
|
||||
ExecuteTransactionLogs,
|
||||
SubmitTransactionLogs,
|
||||
} from 'src/hardhat/modules/dto/ethers.dto';
|
||||
import { parseLogs } from 'src/contract-interact/ethers.helpers';
|
||||
|
||||
export class MultiSigWalletService extends BaseContractService {
|
||||
@ -102,6 +96,7 @@ export class MultiSigWalletService extends BaseContractService {
|
||||
const tx = await contract.executeTransaction(index);
|
||||
|
||||
const txResponse: TransactionReceipt = await tx.wait();
|
||||
console.log('=>(multi-sig.service.ts:99) txResponse', txResponse.logs);
|
||||
const eventParse = parseLogs(txResponse, contract);
|
||||
return {
|
||||
txHash: txResponse.hash,
|
||||
@ -145,8 +140,9 @@ export class MultiSigWalletService extends BaseContractService {
|
||||
return tx;
|
||||
}
|
||||
|
||||
async deposit(dto: DepositMultiSigDto) {
|
||||
async deposit(dto: DepositContractDto) {
|
||||
const { contractAddress, value } = dto;
|
||||
const convertValue = parseEther(value);
|
||||
const signer = await this.providerService.getSigner();
|
||||
|
||||
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
||||
@ -154,7 +150,7 @@ export class MultiSigWalletService extends BaseContractService {
|
||||
|
||||
const tx = await signer.sendTransaction({
|
||||
to: contractAddress,
|
||||
value: BigInt(value),
|
||||
value: convertValue,
|
||||
});
|
||||
|
||||
const txResponse: TransactionReceipt = await tx.wait();
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
|
||||
import { SalariesService } from './salaries.service';
|
||||
import {
|
||||
CreatePayoutDto,
|
||||
GetEmployeeSalariesDto,
|
||||
SalariesDeployDto,
|
||||
SetSalaryDto,
|
||||
} from './salaries.dto';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { DepositContractDto } from '../../../contract-interact/dto/multi-sig.dto';
|
||||
@ApiTags('salaries')
|
||||
@Controller('salaries')
|
||||
export class SalariesController {
|
||||
@ -30,4 +32,14 @@ export class SalariesController {
|
||||
async getSalary(@Body() dto: GetEmployeeSalariesDto) {
|
||||
return this.salariesService.getSalary(dto);
|
||||
}
|
||||
|
||||
@Post('payout')
|
||||
async createPayout(@Body() dto: CreatePayoutDto) {
|
||||
return this.salariesService.createPayout(dto);
|
||||
}
|
||||
|
||||
@Post('deposit')
|
||||
async deposit(@Body() dto: DepositContractDto) {
|
||||
return this.salariesService.deposit(dto);
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ export class SetSalaryDto {
|
||||
@IsNumber()
|
||||
salary: number;
|
||||
}
|
||||
|
||||
export class GetEmployeeSalariesDto {
|
||||
export class GeneralEmpoyeeSalaryDto {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
contractAddress: string;
|
||||
@ -30,3 +29,9 @@ export class GetEmployeeSalariesDto {
|
||||
@IsString()
|
||||
employeeAddress: string;
|
||||
}
|
||||
export class GetEmployeeSalariesDto extends GeneralEmpoyeeSalaryDto {}
|
||||
|
||||
export class CreatePayoutDto extends GeneralEmpoyeeSalaryDto {
|
||||
@IsString()
|
||||
multiSigWallet: string;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { BaseContractService } from '../base-contract.service';
|
||||
import { ethers } from 'ethers';
|
||||
import { ethers, parseEther, TransactionReceipt } from 'ethers';
|
||||
import {
|
||||
CreatePayoutDto,
|
||||
GetEmployeeSalariesDto,
|
||||
SalariesDeployDto,
|
||||
SetSalaryDto,
|
||||
@ -9,6 +10,7 @@ import {
|
||||
import * as hre from 'hardhat';
|
||||
import { MultiSigWalletService } from '../multi-sig/multi-sig.service';
|
||||
import { ProviderService } from '../../../provider/provider.service';
|
||||
import { DepositContractDto } from '../../../contract-interact/dto/multi-sig.dto';
|
||||
|
||||
@Injectable()
|
||||
export class SalariesService extends BaseContractService {
|
||||
@ -69,7 +71,43 @@ export class SalariesService extends BaseContractService {
|
||||
|
||||
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||
|
||||
const answer: string = await contract.getSalary(employeeAddress);
|
||||
return answer;
|
||||
const answer: BigInt = await contract.getSalary(employeeAddress);
|
||||
return {
|
||||
salaryInUsd: answer.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
async createPayout(dto: CreatePayoutDto) {
|
||||
const { employeeAddress, contractAddress, multiSigWallet } = dto;
|
||||
console.log('=>(salaries.service.ts:82) employeeAddress', employeeAddress);
|
||||
const ISubmitMultiSig = new ethers.Interface([
|
||||
'function payoutInETH(address employee)',
|
||||
]);
|
||||
const data = ISubmitMultiSig.encodeFunctionData('payoutInETH', [
|
||||
employeeAddress,
|
||||
]);
|
||||
|
||||
return await this.multiSigWalletService.submitTransaction({
|
||||
contractAddress: multiSigWallet,
|
||||
destination: contractAddress,
|
||||
value: '0',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async deposit(dto: DepositContractDto) {
|
||||
const { contractAddress, value } = dto;
|
||||
const signer = await this.providerService.getSigner();
|
||||
|
||||
const convertValue = parseEther(value);
|
||||
|
||||
const tx = await signer.sendTransaction({
|
||||
to: contractAddress,
|
||||
value: convertValue,
|
||||
});
|
||||
|
||||
const txResponse: TransactionReceipt = await tx.wait();
|
||||
|
||||
return txResponse;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user