ETH Price: $2,778.58 (-0.11%)

Transaction Decoder

Block:
12892877 at Jul-25-2021 02:49:34 AM +UTC
Transaction Fee:
0.0016386 ETH $4.55
Gas Used:
40,965 Gas / 40 Gwei

Account State Difference:

  Address   Before After State Difference Code
(Ethermine)
2,345.581453992086591693 Eth2,345.583092592086591693 Eth0.0016386
0xF2948Eb2...7bffAFf65
0.050841974 Eth
Nonce: 9
0.049203374 Eth
Nonce: 10
0.0016386

Execution Trace

MerkleRedeem.claimWeeks( _liquidityProvider=0xF2948Eb21cD5F5c4E332ffC5238Be657bffAFf65, claims= )
1
{"IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the
    EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view
    returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account)
    external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller\u0027s account to `recipient`.\n *\n *
    Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer
    (address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will
    be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when
    {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n
    /**\n * @dev Sets `amount` as the allowance of `spender` over the caller\u0027s tokens.\n *\n * Returns a boolean value indicating
    whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone
    may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n *
    condition is to first reduce the spender\u0027s allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum
    /EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount)
    external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount`
    is then deducted from the caller\u0027s\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n
     *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool
    );\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that
    `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when
    the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval
    (address indexed owner, address indexed spender, uint256 value);\n}\n"},"MerkleProof.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma
    solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\n */\nlibrary MerkleProof {\n /**\n *
    @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n * defined by `root`. For this, a `proof` must be provided,
    containing\n * sibling hashes on the branch from the leaf to the root of the tree. Each\n * pair of leaves and each pair of pre-images are
    assumed to be sorted.\n */\n function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n
    bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i \u003c proof.length; i++) {\n bytes32 proofElement = proof[i];\n\n
     if (computedHash \u003c= proofElement) {\n // Hash(current computed hash + current element of the proof)\n
    computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n } else {\n // Hash(current element of the proof
    + current computed hash)\n computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n }\n }\n\n
     // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n"},"MerkleRedeem.sol"
    :{"content":"pragma solidity 0.6.8;\npragma experimental ABIEncoderV2;\n\nimport \"./MerkleProof.sol\";\nimport \"./Ownable.sol\";\nimport \"
    ./IERC20.sol\";\n\ncontract MerkleRedeem is Ownable {\n\n IERC20 public token;\n\n event Claimed(address _claimant, uint256 _balance);\n\n
     // Recorded weeks\n mapping(uint =\u003e bytes32) public weekMerkleRoots;\n mapping(uint =\u003e mapping(address =\u003e bool)) public
    claimed;\n\n constructor(\n address _token\n ) public {\n token = IERC20(_token);\n }\n\n function disburse(\n
    address _liquidityProvider,\n uint _balance\n )\n private\n {\n if (_balance \u003e 0) {\n emit Claimed
    (_liquidityProvider, _balance);\n require(token.transfer(_liquidityProvider, _balance), \"ERR_TRANSFER_FAILED\");\n }\n }\n\n
     function claimWeek(\n address _liquidityProvider,\n uint _week,\n uint _claimedBalance,\n bytes32[] memory
    _merkleProof\n )\n public\n {\n require(!claimed[_week][_liquidityProvider]);\n require(verifyClaim(_liquidityProvider,
    _week, _claimedBalance, _merkleProof), \u0027Incorrect merkle proof\u0027);\n\n claimed[_week][_liquidityProvider] = true;\n disburse
    (_liquidityProvider, _claimedBalance);\n }\n\n struct Claim {\n uint week;\n uint balance;\n bytes32[] merkleProof;\n
     }\n\n function claimWeeks(\n address _liquidityProvider,\n Claim[] memory claims\n )\n public\n {\n uint
    totalBalance = 0;\n Claim memory claim ;\n for(uint i = 0; i \u003c claims.length; i++) {\n claim = claims[i];\n\n
     require(!claimed[claim.week][_liquidityProvider]);\n require(verifyClaim(_liquidityProvider, claim.week, claim.balance, claim
    .merkleProof), \u0027Incorrect merkle proof\u0027);\n\n totalBalance += claim.balance;\n claimed[claim
    .week][_liquidityProvider] = true;\n }\n disburse(_liquidityProvider, totalBalance);\n }\n\n function claimStatus(\n
    address _liquidityProvider,\n uint _begin,\n uint _end\n )\n external\n view\n returns (bool[] memory)\n
    {\n uint size = 1 + _end - _begin;\n bool[] memory arr = new bool[](size);\n for(uint i = 0; i \u003c size; i++) {\n
     arr[i] = claimed[_begin + i][_liquidityProvider];\n }\n return arr;\n }\n\n function merkleRoots(\n uint _begin,\n
     uint _end\n ) \n external\n view \n returns (bytes32[] memory)\n {\n uint size = 1 + _end - _begin;\n
    bytes32[] memory arr = new bytes32[](size);\n for(uint i = 0; i \u003c size; i++) {\n arr[i] = weekMerkleRoots[_begin + i];\n
     }\n return arr;\n }\n\n function verifyClaim(\n address _liquidityProvider,\n uint _week,\n uint
    _claimedBalance,\n bytes32[] memory _merkleProof\n )\n public\n view\n returns (bool valid)\n {\n bytes32
    leaf = keccak256(abi.encodePacked(_liquidityProvider, _claimedBalance));\n return MerkleProof.verify(_merkleProof, weekMerkleRoots[_week],
    leaf);\n }\n\n function seedAllocations(\n uint _week,\n bytes32 _merkleRoot,\n uint _totalAllocation\n )\n
    external\n onlyOwner\n {\n require(weekMerkleRoots[_week] == bytes32(0), \"cannot rewrite merkle root\");\n
    weekMerkleRoots[_week] = _merkleRoot;\n\n require(token.transferFrom(msg.sender, address(this), _totalAllocation), \"ERR_TRANSFER_FAILED\"
    );\n }\n}\n"},"Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/*\n * @dev Provides information about the
    current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg
    .data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying
    for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate,
    library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n
    return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability
    warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n\n/**\n * @dev
    Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n
    * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with
    {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to
    your functions to restrict their use to\n * the owner.\n */\ncontract Ownable is Context {\n address private _owner;\n\n event
    OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the
    deployer as the initial owner.\n */\n constructor () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n
     emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n
    function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than
    the owner.\n */\n modifier onlyOwner() {\n require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n
    }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be
    called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any
    functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n emit
    OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new
    account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual
    onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner,
    newOwner);\n _owner = newOwner;\n }\n}\n"}}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX