Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PullRewardsTransferStrategy
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 100000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.10; import {IPullRewardsTransferStrategy} from '../interfaces/IPullRewardsTransferStrategy.sol'; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; import {TransferStrategyBase} from './TransferStrategyBase.sol'; import {GPv2SafeERC20} from '@aave/core-v3/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; /** * @title PullRewardsTransferStrategy * @notice Transfer strategy that pulls ERC20 rewards from an external account to the user address. * The external account could be a smart contract or EOA that must approve to the PullRewardsTransferStrategy contract address. * @author Aave **/ contract PullRewardsTransferStrategy is TransferStrategyBase, IPullRewardsTransferStrategy { using GPv2SafeERC20 for IERC20; address internal immutable REWARDS_VAULT; constructor( address incentivesController, address rewardsAdmin, address rewardsVault ) TransferStrategyBase(incentivesController, rewardsAdmin) { REWARDS_VAULT = rewardsVault; } /// @inheritdoc TransferStrategyBase function performTransfer( address to, address reward, uint256 amount ) external override(TransferStrategyBase, ITransferStrategyBase) onlyIncentivesController returns (bool) { IERC20(reward).safeTransferFrom(REWARDS_VAULT, to, amount); return true; } /// @inheritdoc IPullRewardsTransferStrategy function getRewardsVault() external view returns (address) { return REWARDS_VAULT; } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.10; import {ITransferStrategyBase} from './ITransferStrategyBase.sol'; /** * @title IPullRewardsTransferStrategy * @author Aave **/ interface IPullRewardsTransferStrategy is ITransferStrategyBase { /** * @return Address of the rewards vault */ function getRewardsVault() external view returns (address); }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.10; interface ITransferStrategyBase { event EmergencyWithdrawal( address indexed caller, address indexed token, address indexed to, uint256 amount ); /** * @dev Perform custom transfer logic via delegate call from source contract to a TransferStrategy implementation * @param to Account to transfer rewards * @param reward Address of the reward token * @param amount Amount to transfer to the "to" address parameter * @return Returns true bool if transfer logic succeeds */ function performTransfer( address to, address reward, uint256 amount ) external returns (bool); /** * @return Returns the address of the Incentives Controller */ function getIncentivesController() external view returns (address); /** * @return Returns the address of the Rewards admin */ function getRewardsAdmin() external view returns (address); /** * @dev Perform an emergency token withdrawal only callable by the Rewards admin * @param token Address of the token to withdraw funds from this contract * @param to Address of the recipient of the withdrawal * @param amount Amount of the withdrawal */ function emergencyWithdrawal( address token, address to, uint256 amount ) external; }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.10; import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol'; import {GPv2SafeERC20} from '@aave/core-v3/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol'; import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; /** * @title TransferStrategyStorage * @author Aave **/ abstract contract TransferStrategyBase is ITransferStrategyBase { using GPv2SafeERC20 for IERC20; address internal immutable INCENTIVES_CONTROLLER; address internal immutable REWARDS_ADMIN; constructor(address incentivesController, address rewardsAdmin) { INCENTIVES_CONTROLLER = incentivesController; REWARDS_ADMIN = rewardsAdmin; } /** * @dev Modifier for incentives controller only functions */ modifier onlyIncentivesController() { require(INCENTIVES_CONTROLLER == msg.sender, 'CALLER_NOT_INCENTIVES_CONTROLLER'); _; } /** * @dev Modifier for reward admin only functions */ modifier onlyRewardsAdmin() { require(msg.sender == REWARDS_ADMIN, 'ONLY_REWARDS_ADMIN'); _; } /// @inheritdoc ITransferStrategyBase function getIncentivesController() external view override returns (address) { return INCENTIVES_CONTROLLER; } /// @inheritdoc ITransferStrategyBase function getRewardsAdmin() external view override returns (address) { return REWARDS_ADMIN; } /// @inheritdoc ITransferStrategyBase function performTransfer( address to, address reward, uint256 amount ) external virtual returns (bool); /// @inheritdoc ITransferStrategyBase function emergencyWithdrawal( address token, address to, uint256 amount ) external onlyRewardsAdmin { IERC20(token).safeTransfer(to, amount); emit EmergencyWithdrawal(msg.sender, token, to, amount); } }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity 0.8.10; import {IERC20} from '../../openzeppelin/contracts/IERC20.sol'; /// @title Gnosis Protocol v2 Safe ERC20 Transfer Library /// @author Gnosis Developers /// @dev Gas-efficient version of Openzeppelin's SafeERC20 contract. library GPv2SafeERC20 { /// @dev Wrapper around a call to the ERC20 function `transfer` that reverts /// also when the token returns `false`. function safeTransfer(IERC20 token, address to, uint256 value) internal { bytes4 selector_ = token.transfer.selector; // solhint-disable-next-line no-inline-assembly assembly { let freeMemoryPointer := mload(0x40) mstore(freeMemoryPointer, selector_) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 36), value) if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } require(getLastTransferResult(token), 'GPv2: failed transfer'); } /// @dev Wrapper around a call to the ERC20 function `transferFrom` that /// reverts also when the token returns `false`. function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { bytes4 selector_ = token.transferFrom.selector; // solhint-disable-next-line no-inline-assembly assembly { let freeMemoryPointer := mload(0x40) mstore(freeMemoryPointer, selector_) mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) mstore(add(freeMemoryPointer, 68), value) if iszero(call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } require(getLastTransferResult(token), 'GPv2: failed transferFrom'); } /// @dev Verifies that the last return was a successful `transfer*` call. /// This is done by checking that the return data is either empty, or /// is a valid ABI encoded boolean. function getLastTransferResult(IERC20 token) private view returns (bool success) { // NOTE: Inspecting previous return data requires assembly. Note that // we write the return data to memory 0 in the case where the return // data size is 32, this is OK since the first 64 bytes of memory are // reserved by Solidy as a scratch space that can be used within // assembly blocks. // <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html> // solhint-disable-next-line no-inline-assembly assembly { /// @dev Revert with an ABI encoded Solidity error with a message /// that fits into 32-bytes. /// /// An ABI encoded Solidity error has the following memory layout: /// /// ------------+---------------------------------- /// byte range | value /// ------------+---------------------------------- /// 0x00..0x04 | selector("Error(string)") /// 0x04..0x24 | string offset (always 0x20) /// 0x24..0x44 | string length /// 0x44..0x64 | string value, padded to 32-bytes function revertWithMessage(length, message) { mstore(0x00, '\x08\xc3\x79\xa0') mstore(0x04, 0x20) mstore(0x24, length) mstore(0x44, message) revert(0x00, 0x64) } switch returndatasize() // Non-standard ERC20 transfer without return. case 0 { // NOTE: When the return data size is 0, verify that there // is code at the address. This is done in order to maintain // compatibility with Solidity calling conventions. // <https://docs.soliditylang.org/en/v0.7.6/control-structures.html#external-function-calls> if iszero(extcodesize(token)) { revertWithMessage(20, 'GPv2: not a contract') } success := 1 } // Standard ERC20 transfer returning boolean success value. case 32 { returndatacopy(0, 0, returndatasize()) // NOTE: For ABI encoding v1, any non-zero value is accepted // as `true` for a boolean. In order to stay compatible with // OpenZeppelin's `SafeERC20` library which is known to work // with the existing ERC20 implementation we care about, // make sure we return success for any non-zero return value // from the `transfer*` call. success := iszero(iszero(mload(0))) } default { revertWithMessage(31, 'GPv2: malformed transfer result') } } } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
{ "remappings": [ "@aave/core-v3/=lib/aave-v3-core/", "aave-helpers/=lib/aave-helpers/src/", "@uniswap/v3-core/=lib/v3-core/", "solidity-utils/=lib/V2-V3-migration-helpers/lib/solidity-utils/src/", "@aave/periphery-v3/=lib/aave-address-book/lib/aave-v3-periphery/", "V2-V3-migration-helpers/=lib/V2-V3-migration-helpers/", "aave-address-book/=lib/aave-address-book/src/", "aave-v3-core/=lib/aave-v3-core/", "aave-v3-periphery/=lib/aave-v3-periphery/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "dss-interfaces/=lib/dss-test/lib/dss-interfaces/src/", "dss-test/=lib/dss-test/src/", "forge-std/=lib/forge-std/src/", "governance-crosschain-bridges/=lib/aave-helpers/lib/governance-crosschain-bridges/" ], "optimizer": { "enabled": true, "runs": 100000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"incentivesController","type":"address"},{"internalType":"address","name":"rewardsAdmin","type":"address"},{"internalType":"address","name":"rewardsVault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdrawal","type":"event"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getIncentivesController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardsAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardsVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"reward","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"performTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e060405234801561001057600080fd5b5060405161078038038061078083398101604081905261002f91610068565b6001600160a01b0392831660805290821660a0521660c0526100ab565b80516001600160a01b038116811461006357600080fd5b919050565b60008060006060848603121561007d57600080fd5b6100868461004c565b92506100946020850161004c565b91506100a26040850161004c565b90509250925092565b60805160a05160c0516106936100ed6000396000818161011801526101fe01526000818160f201526102460152600081816096015261014001526106936000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80638d8e5da7116100505780638d8e5da7146100db578063c6255443146100f0578063e23ddec51461011657600080fd5b806316beb9821461006c57806375d2641314610094575b600080fd5b61007f61007a366004610621565b61013c565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161008b565b6100ee6100e9366004610621565b61022e565b005b7f00000000000000000000000000000000000000000000000000000000000000006100b6565b7f00000000000000000000000000000000000000000000000000000000000000006100b6565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146101e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f43414c4c45525f4e4f545f494e43454e54495645535f434f4e54524f4c4c455260448201526064015b60405180910390fd5b61022473ffffffffffffffffffffffffffffffffffffffff84167f00000000000000000000000000000000000000000000000000000000000000008685610371565b5060019392505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f4e4c595f524557415244535f41444d494e000000000000000000000000000060448201526064016101d9565b6102ee73ffffffffffffffffffffffffffffffffffffffff84168383610453565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f7dc4ea712e6400e67a5abca1a983e5c420c386c19936dc120cd860b50b8e25798460405161036491815260200190565b60405180910390a4505050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff8581166004840152841660248301526044820183905290600080606483828a5af16103dc573d6000803e3d6000fd5b506103e68561052c565b61044c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f475076323a206661696c6564207472616e7366657246726f6d0000000000000060448201526064016101d9565b5050505050565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff84166004830152602482018390529060008060448382895af16104b6573d6000803e3d6000fd5b506104c08461052c565b610526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f475076323a206661696c6564207472616e73666572000000000000000000000060448201526064016101d9565b50505050565b600061056c565b7f08c379a00000000000000000000000000000000000000000000000000000000060005260206004528060245250806044525060646000fd5b3d80156105ab57602081146105e5576105a67f475076323a206d616c666f726d6564207472616e7366657220726573756c7400601f610533565b6105f2565b823b6105dc576105dc7f475076323a206e6f74206120636f6e74726163740000000000000000000000006014610533565b600191506105f2565b3d6000803e600051151591505b50919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461061c57600080fd5b919050565b60008060006060848603121561063657600080fd5b61063f846105f8565b925061064d602085016105f8565b915060408401359050925092509256fea2646970667358221220ee74493065721b2d79a290b32da28fb19c344a659ee8e187a7cc0f0e703299ae64736f6c634300080a00330000000000000000000000004370d3b6c9588e02ce9d22e684387859c7ff5b340000000000000000000000003300f198988e4c9c63f75df86de36421f06af8c40000000000000000000000008076807464dac94ac8aa1f7af31b58f73bd88a27
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100675760003560e01c80638d8e5da7116100505780638d8e5da7146100db578063c6255443146100f0578063e23ddec51461011657600080fd5b806316beb9821461006c57806375d2641314610094575b600080fd5b61007f61007a366004610621565b61013c565b60405190151581526020015b60405180910390f35b7f0000000000000000000000004370d3b6c9588e02ce9d22e684387859c7ff5b345b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161008b565b6100ee6100e9366004610621565b61022e565b005b7f0000000000000000000000003300f198988e4c9c63f75df86de36421f06af8c46100b6565b7f0000000000000000000000008076807464dac94ac8aa1f7af31b58f73bd88a276100b6565b60007f0000000000000000000000004370d3b6c9588e02ce9d22e684387859c7ff5b3473ffffffffffffffffffffffffffffffffffffffff1633146101e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f43414c4c45525f4e4f545f494e43454e54495645535f434f4e54524f4c4c455260448201526064015b60405180910390fd5b61022473ffffffffffffffffffffffffffffffffffffffff84167f0000000000000000000000008076807464dac94ac8aa1f7af31b58f73bd88a278685610371565b5060019392505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003300f198988e4c9c63f75df86de36421f06af8c416146102cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f4e4c595f524557415244535f41444d494e000000000000000000000000000060448201526064016101d9565b6102ee73ffffffffffffffffffffffffffffffffffffffff84168383610453565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f7dc4ea712e6400e67a5abca1a983e5c420c386c19936dc120cd860b50b8e25798460405161036491815260200190565b60405180910390a4505050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff8581166004840152841660248301526044820183905290600080606483828a5af16103dc573d6000803e3d6000fd5b506103e68561052c565b61044c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f475076323a206661696c6564207472616e7366657246726f6d0000000000000060448201526064016101d9565b5050505050565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff84166004830152602482018390529060008060448382895af16104b6573d6000803e3d6000fd5b506104c08461052c565b610526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f475076323a206661696c6564207472616e73666572000000000000000000000060448201526064016101d9565b50505050565b600061056c565b7f08c379a00000000000000000000000000000000000000000000000000000000060005260206004528060245250806044525060646000fd5b3d80156105ab57602081146105e5576105a67f475076323a206d616c666f726d6564207472616e7366657220726573756c7400601f610533565b6105f2565b823b6105dc576105dc7f475076323a206e6f74206120636f6e74726163740000000000000000000000006014610533565b600191506105f2565b3d6000803e600051151591505b50919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461061c57600080fd5b919050565b60008060006060848603121561063657600080fd5b61063f846105f8565b925061064d602085016105f8565b915060408401359050925092509256fea2646970667358221220ee74493065721b2d79a290b32da28fb19c344a659ee8e187a7cc0f0e703299ae64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004370d3b6c9588e02ce9d22e684387859c7ff5b340000000000000000000000003300f198988e4c9c63f75df86de36421f06af8c40000000000000000000000008076807464dac94ac8aa1f7af31b58f73bd88a27
-----Decoded View---------------
Arg [0] : incentivesController (address): 0x4370D3b6C9588E02ce9D22e684387859c7Ff5b34
Arg [1] : rewardsAdmin (address): 0x3300f198988e4C9C63F75dF86De36421f06af8c4
Arg [2] : rewardsVault (address): 0x8076807464DaC94Ac8Aa1f7aF31b58F73bD88A27
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000004370d3b6c9588e02ce9d22e684387859c7ff5b34
Arg [1] : 0000000000000000000000003300f198988e4c9c63f75df86de36421f06af8c4
Arg [2] : 0000000000000000000000008076807464dac94ac8aa1f7af31b58f73bd88a27
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.