클레이 전송관련 오류인데, 원인 파악이 안되서 질문드립니다

  1. sendMoneyOrEscrow(_makePayable(maintainer), amount);
    sendMoneyOrEscrow를 호출할 때, amount값이 3410 peb 이하 일 때는 정상 호출이 되나, 3420 peb 이상일 때 아래와 같은 에러가 납니다.

/Users/lee/.mkt/node_modules/caver-js/packages/caver-core-method/src/index.js:759
new Error(${errors.txErrorTable[txError]}\n ${receiptJSON}),
^

Error: evm: execution reverted
{
“blockHash”: “0xc6506848b1d8e2ec78aa48ac64ac08ea4e318fd4c606a4bfe7ce3b4fcb2057c6”,
“blockNumber”: 67598406,
“contractAddress”: null,
“from”: “0x7c0631848c7e21020077edab7c2350d289a46b34”,
“gas”: “0x493e0”,
“gasPrice”: “0x5d21dba00”,
“gasUsed”: 248461,
“input”: “0xcce7ec13000000000000000000000000308199c52097d8b52839b81c25816cd9beaca0100000000000000000000000000000000000000000000000000000000000000000”,
“logsBloom”: “0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”,
“nonce”: “0x90”,
“senderTxHash”: “0x8826d68a973af671e3244727de5a4293c02684e3a1312069927e4b3f169d1992”,
“signatures”: [
{
“V”: “0x7f5”,
“R”: “0x4ea4d801976cf5f1ad171aa0eeb5af1cd686b8f3aa86d1cddfe0e24a893185a7”,
“S”: “0x107e041dafd5978c5882ec092b11b9908891a0c597eab130d64b95e2e0b45579”
}
],
“status”: false,
“to”: “0x07749c7a4487506651bac835dd9c5c3cb650f103”,
“transactionHash”: “0x8826d68a973af671e3244727de5a4293c02684e3a1312069927e4b3f169d1992”,
“transactionIndex”: 0,
“txError”: “0x9”,
“type”: “TxTypeSmartContractExecution”,
“typeInt”: 48,
“value”: “0x280a”,
“events”: {}
}
at checkForNormalTx (/Users/lee/.3pm/node_modules/caver-js/packages/caver-core-method/src/index.js:759:17)
at /Users/lee/.3pm/node_modules/caver-js/packages/caver-core-method/src/index.js:636:23
at processTicksAndRejections (node:internal/process/task_queues:94:5)

  • 관련 소스는 아래와 같이 첨부합니다.
contract Context {
    constructor () internal { }
 
    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; 
        return msg.data;
    }
}
contract Secondary is Context {
    address private _primary;

    event PrimaryTransferred(
        address recipient
    );

    constructor () internal {
        address msgSender = _msgSender();
        _primary = msgSender;
        emit PrimaryTransferred(msgSender);
    }

    modifier onlyPrimary() {
        require(_msgSender() == _primary, "Secondary: caller is not the primary account");
        _;
    }

    function primary() public view returns (address) {
        return _primary;
    }

    function transferPrimary(address recipient) public onlyPrimary {
        require(recipient != address(0), "Secondary: new primary is the zero address");
        _primary = recipient;
        emit PrimaryTransferred(recipient);
    }
}
contract Escrow is Secondary {
    using SafeMath for uint256;
    using Address for address payable;

    event Deposited(address indexed payee, uint256 weiAmount);
    event Withdrawn(address indexed payee, uint256 weiAmount);

    mapping(address => uint256) private _deposits;

    function depositsOf(address payee) public view returns (uint256) {
        return _deposits[payee];
    }

    function deposit(address payee) public onlyPrimary payable {
        uint256 amount = msg.value;
        _deposits[payee] = _deposits[payee].add(amount);

        emit Deposited(payee, amount);
    }

    function withdraw(address payable payee) public onlyPrimary {
        uint256 payment = _deposits[payee];

        _deposits[payee] = 0;

        payee.transfer(payment);

        emit Withdrawn(payee, payment);
    }

    function withdrawWithGas(address payable payee) public onlyPrimary {
        uint256 payment = _deposits[payee];

        _deposits[payee] = 0;

        payee.sendValue(payment);

        emit Withdrawn(payee, payment);
    }
}
contract PullPayment {
    Escrow private _escrow;

    constructor () internal {
        _escrow = new Escrow();
    }

    function withdrawPayments(address payable payee) public {
        _escrow.withdraw(payee);
    }

    function withdrawPaymentsWithGas(address payable payee) external {
        _escrow.withdrawWithGas(payee);
    }

    function payments(address dest) public view returns (uint256) {
        return _escrow.depositsOf(dest);
    }

    function _asyncTransfer(address dest, uint256 amount) internal {
        _escrow.deposit.value(amount)(dest);
    }
}
interface ITxProxy {
    function sendMoney(address payable _to) external payable;
}
contract TxProxy is ITxProxy {
    function sendMoney(address payable _to) external payable {
        _to.transfer(msg.value);
    }
}
contract MaybeSendMoney {
    TxProxy proxy;

    constructor() internal {
        proxy = new TxProxy();
    }

    function maybeSendMoney(address payable _to, uint256 _value) internal returns (bool)
    {
        (bool success, bytes memory _) = address(proxy).call.value(_value)( abi.encodeWithSignature("sendMoney(address)", _to));
        return success;
    }
}
contract SendMoneyOrEscrow is Ownable, MaybeSendMoney, PullPayment {
    function sendMoneyOrEscrow(address payable _to, uint256 _value) internal {
        bool successfulTransfer = maybeSendMoney(_to, _value);
        if (!successfulTransfer) {
            _asyncTransfer(_to, _value);
        }
    }
}

안녕하세요

다음의 각각의 상황에서 실제로 전송이 발생되었는지 확인하시면 좋을 것 같습니다.

  • 정상 호출 상황에서 (3410 peb)
  • revert 에러 상황에서 (3420 peb)

또한, 전송 전의 balance도 확인하시면 좋을 것 같습니다.

안타깝게도, 보내주신 소스코드만으로는 정확하게 어디서 에러가 났는지 알 수 없을 것 같습니다.
revert 에러의 자세한 분석이 필요하시다면, 다음 문서를 참고하셔서 revertTracer를 활용하셔서 분석해보셔도 좋을 것 같습니다. 스마트 컨트랙트 modifier 관련 질문입니다