Address Contract Partially Verified
Address
0x57f2D75bd84bFb6912971713D0Fa326402A0aC95
Balance
0 ETH
Nonce
1
Code Size
7054 bytes
Creator
0xB81e9C08...E86F at tx 0x5ed3b0c1...e44f62
Indexed Transactions
0
Contract Bytecode
7054 bytes
0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063851f1d9e116100de578063b470aade11610097578063dbe6254511610071578063dbe6254514610371578063e5d7ac0814610398578063f2fde38b146103ab578063fc0c546a146103be57600080fd5b8063b470aade14610315578063c1cc70101461033c578063c884ef831461035157600080fd5b8063851f1d9e146102985780638da5cb5b146102bf578063a2309ff8146102d0578063a7cac846146102d9578063ab39f828146102f9578063b23ac4101461030c57600080fd5b8063477d566b1161014b57806359770438116101255780635977043814610262578063715018a614610275578063766a4afb1461027d5780637ecc2b561461029057600080fd5b8063477d566b146102255780634e4f8289146102505780635311135e1461025957600080fd5b806310098ad51461019357806319039e89146101c657806321df0da7146101db578063360ed9c2146101e35780633b5bf85d146101eb578063402914f514610212575b600080fd5b6101b36101a1366004611573565b60046020526000908152604090205481565b6040519081526020015b60405180910390f35b6101d96101d43660046116d6565b6103e5565b005b6101d96104c2565b6101b361052a565b6101b37f00000000000000000000000000000000000000000000043c33c193756480000081565b6101b3610220366004611573565b61053b565b61023861023336600461173a565b610689565b6040516001600160a01b0390911681526020016101bd565b6101b360025481565b6101b360065481565b6101d9610270366004611573565b61069c565b6101d96106d2565b6101d961028b366004611753565b610708565b6001546101b3565b6101b37f00000000000000000000000000000000000000000000000000000000635f990381565b6000546001600160a01b0316610238565b6101b360015481565b6101b36102e7366004611573565b60036020526000908152604090205481565b6101d96103073660046117e4565b610906565b6101b361271081565b6101b37f000000000000000000000000000000000000000000000000000000000000000181565b610344610976565b6040516101bd919061187c565b6101b361035f366004611573565b60056020526000908152604090205481565b6101b37f00000000000000000000000000000000000000000000000000012cc242ae005681565b6101d96103a63660046118c9565b610a26565b6101d96103b9366004611573565b610c30565b6102387f00000000000000000000000056bb5d139ecc91992587cedba55794d7feea489e81565b6000546001600160a01b031633146104185760405162461bcd60e51b815260040161040f90611950565b60405180910390fd5b610420610cc8565b508051825114801561043b57506104376007610e23565b8251145b6104575760405162461bcd60e51b815260040161040f90611985565b60006104638383610e2d565b905080612710146104865760405162461bcd60e51b815260040161040f906119ad565b7f017eac0d653731acc55226069632b58d62d18416bf3c91db8b81cad3e784a4da836040516104b59190611a0f565b60405180910390a1505050565b6104ca610cc8565b507f00000000000000000000000056bb5d139ecc91992587cedba55794d7feea489e60005b6104f96007610e23565b8110156105265761051461050e60078361102d565b83611040565b8061051e81611a38565b9150506104ef565b5050565b60006105366007610e23565b905090565b600154600254600091907f00000000000000000000000000000000000000000000043c33c19375648000009083907f00000000000000000000000000000000000000000000000000012cc242ae0056907f0000000000000000000000000000000000000000000000000000000000000001906105b79042611a53565b6105c19190611a6a565b6105cb9190611a8c565b9050816105d88483611aab565b11156105eb576105e88383611a53565b90505b60006105f860078761116f565b610603576000610642565b6001600160a01b038616600090815260036020526040902054600654612710919061062e9085611aab565b6106389190611a8c565b6106429190611a6a565b6001600160a01b038716600090815260056020908152604080832054600490925290912054919250906106759083611aab565b61067f9190611a53565b9695505050505050565b600061069660078361102d565b92915050565b6106a4610cc8565b506106cf817f00000000000000000000000056bb5d139ecc91992587cedba55794d7feea489e611040565b50565b6000546001600160a01b031633146106fc5760405162461bcd60e51b815260040161040f90611950565b6107066000611191565b565b6000546001600160a01b031633146107325760405162461bcd60e51b815260040161040f90611950565b8051825114801561074c57506107486007610e23565b8251145b6107685760405162461bcd60e51b815260040161040f90611985565b600084116107ab5760405162461bcd60e51b815260206004820152601060248201526f1a5b98dbdc9c9958dd081dd95a59da1d60821b604482015260640161040f565b6107b3610cc8565b506107bf60078661116f565b156107fc5760405162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015260640161040f565b60006108088383610e2d565b90506108148582611aab565b905080612710146108375760405162461bcd60e51b815260040161040f906119ad565b6108426007876111e1565b506001600160a01b03861660008181526003602052604090208690553b1515801561086a5750835b156108c357856001600160a01b0316633e0b1a236040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156108aa57600080fd5b505af11580156108be573d6000803e3d6000fd5b505050505b7fd8ff9bb7e04b358e889d2f4d18c09676379b00222a8ae18dd2517d6afe57b4d18686856040516108f693929190611ac3565b60405180910390a1505050505050565b61090e610cc8565b507f00000000000000000000000056bb5d139ecc91992587cedba55794d7feea489e60005b82518110156109715761095f83828151811061095157610951611af3565b602002602001015183611040565b8061096981611a38565b915050610933565b505050565b606060006109846007610e23565b905060008167ffffffffffffffff8111156109a1576109a161158e565b6040519080825280602002602001820160405280156109ca578160200160208202803683370190505b50905060005b82811015610a1f576109e360078261102d565b8282815181106109f5576109f5611af3565b6001600160a01b039092166020928302919091019091015280610a1781611a38565b9150506109d0565b5092915050565b6000546001600160a01b03163314610a505760405162461bcd60e51b815260040161040f90611950565b80518251148015610a7657506001610a686007610e23565b610a729190611a53565b8251145b610a925760405162461bcd60e51b815260040161040f90611985565b610a9a610cc8565b5060065460005b610aab6007610e23565b811015610b36576000610abf60078361102d565b6001600160a01b0381166000908152600460209081526040808320546003909252909120549192509061271090610af69086611a8c565b610b009190611a6a565b610b0a9190611aab565b6001600160a01b0390911660009081526004602052604090205580610b2e81611a38565b915050610aa1565b506000600655610b476007866111f6565b506001600160a01b0385166000908152600360205260408120819055610b6d8484610e2d565b90506001600160a01b0386163b15158015610b855750845b15610bde57856001600160a01b0316633e0b1a236040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610bc557600080fd5b505af1158015610bd9573d6000803e3d6000fd5b505050505b8061271014610bff5760405162461bcd60e51b815260040161040f906119ad565b7ff3c1cb27bbb141483f4a6295e38950695bd39351665be2f1aaeb98487e53e3e786856040516108f6929190611b09565b6000546001600160a01b03163314610c5a5760405162461bcd60e51b815260040161040f90611950565b6001600160a01b038116610cbf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161040f565b6106cf81611191565b6001546000907f00000000000000000000000000000000000000000000043c33c1937564800000828183108015610d075750610d046007610e23565b15155b15610e04576000610d1661120b565b90506000610d447f00000000000000000000000000000000000000000000000000012cc242ae005683611a8c565b90506000848211610d555781610d57565b845b9050610d638682611a53565b93508360016000828254610d779190611aab565b90915550506040516340c10f1960e01b8152306004820152602481018590527f00000000000000000000000056bb5d139ecc91992587cedba55794d7feea489e6001600160a01b0316906340c10f1990604401600060405180830381600087803b158015610de457600080fd5b505af1158015610df8573d6000803e3d6000fd5b50504260025550505050505b8060066000828254610e169190611aab565b9091555090949350505050565b6000610696825490565b6006546000908190815b855181101561101f576000868281518110610e5457610e54611af3565b602002602001015111610e9c5760405162461bcd60e51b815260206004820152601060248201526f1a5b98dbdc9c9958dd081dd95a59da1d60821b604482015260640161040f565b858181518110610eae57610eae611af3565b602002602001015183610ec19190611aab565b92506000610ed060078361102d565b6001600160a01b03811660009081526005602090815260408083205460048352818420546003909352922054929350909161271090610f0f9087611a8c565b610f199190611a6a565b610f239190611aab565b610f2d9190611a53565b6001600160a01b03821660009081526004602090815260408083209390935560059052908120558651879083908110610f6857610f68611af3565b6020908102919091018101516001600160a01b038316600081815260039093526040909220553b15158015610fb35750858281518110610faa57610faa611af3565b60200260200101515b1561100c57806001600160a01b0316633e0b1a236040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ff357600080fd5b505af1158015611007573d6000803e3d6000fd5b505050505b508061101781611a38565b915050610e37565b505060006006559392505050565b60006110398383611262565b9392505050565b6001600160a01b0382166000908152600360205260408120546006546127109161106991611a8c565b6110739190611a6a565b6001600160a01b038416600090815260056020908152604080832054600490925282205492935090916110a69084611aab565b6110b09190611a53565b6001600160a01b0385166000908152600560205260409020549091506110d69083611a53565b6001600160a01b038516600090815260056020526040812080549091906110fe908490611aab565b90915550506001600160a01b03841660009081526004602052604081205580156111695761112c848261128c565b6040516001600160a01b03851681527f689e9fbdf844fc04557a4a9000a12d7e50c0ae7e1f21600e307bf55ea92afa079060200160405180910390a15b50505050565b6001600160a01b03811660009081526001830160205260408120541515611039565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000611039836001600160a01b038416611415565b6000611039836001600160a01b038416611464565b60007f00000000000000000000000000000000000000000000000000000000000000016112587f00000000000000000000000000000000000000000000000000000000635f990342611a53565b6105369190611a6a565b600082600001828154811061127957611279611af3565b9060005260206000200154905092915050565b6040516370a0823160e01b81523060048201527f00000000000000000000000056bb5d139ecc91992587cedba55794d7feea489e906000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156112f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113199190611b35565b905082811061139b5760405163a9059cbb60e01b81526001600160a01b0385811660048301526024820185905283169063a9059cbb906044016020604051808303816000875af1158015611371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113959190611b4e565b50611169565b60405163a9059cbb60e01b81526001600160a01b0385811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af11580156113ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140e9190611b4e565b5050505050565b600081815260018301602052604081205461145c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610696565b506000610696565b6000818152600183016020526040812054801561154d576000611488600183611a53565b855490915060009061149c90600190611a53565b90508181146115015760008660000182815481106114bc576114bc611af3565b90600052602060002001549050808760000184815481106114df576114df611af3565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061151257611512611b6b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610696565b6000915050610696565b80356001600160a01b038116811461156e57600080fd5b919050565b60006020828403121561158557600080fd5b61103982611557565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115cd576115cd61158e565b604052919050565b600067ffffffffffffffff8211156115ef576115ef61158e565b5060051b60200190565b600082601f83011261160a57600080fd5b8135602061161f61161a836115d5565b6115a4565b82815260059290921b8401810191818101908684111561163e57600080fd5b8286015b848110156116595780358352918301918301611642565b509695505050505050565b80151581146106cf57600080fd5b600082601f83011261168357600080fd5b8135602061169361161a836115d5565b82815260059290921b840181019181810190868411156116b257600080fd5b8286015b848110156116595780356116c981611664565b83529183019183016116b6565b600080604083850312156116e957600080fd5b823567ffffffffffffffff8082111561170157600080fd5b61170d868387016115f9565b9350602085013591508082111561172357600080fd5b5061173085828601611672565b9150509250929050565b60006020828403121561174c57600080fd5b5035919050565b600080600080600060a0868803121561176b57600080fd5b61177486611557565b945060208601359350604086013561178b81611664565b9250606086013567ffffffffffffffff808211156117a857600080fd5b6117b489838a016115f9565b935060808801359150808211156117ca57600080fd5b506117d788828901611672565b9150509295509295909350565b600060208083850312156117f757600080fd5b823567ffffffffffffffff81111561180e57600080fd5b8301601f8101851361181f57600080fd5b803561182d61161a826115d5565b81815260059190911b8201830190838101908783111561184c57600080fd5b928401925b828410156118715761186284611557565b82529284019290840190611851565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156118bd5783516001600160a01b031683529284019291840191600101611898565b50909695505050505050565b600080600080608085870312156118df57600080fd5b6118e885611557565b935060208501356118f881611664565b9250604085013567ffffffffffffffff8082111561191557600080fd5b611921888389016115f9565b9350606087013591508082111561193757600080fd5b5061194487828801611672565b91505092959194509250565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600e908201526d1b195b99dd1a1cc808595c5d585b60921b604082015260600190565b6020808252600d908201526c696e636f72726563742073756d60981b604082015260600190565b600081518084526020808501945080840160005b83811015611a04578151875295820195908201906001016119e8565b509495945050505050565b60208152600061103960208301846119d4565b634e487b7160e01b600052601160045260246000fd5b6000600019821415611a4c57611a4c611a22565b5060010190565b600082821015611a6557611a65611a22565b500390565b600082611a8757634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611aa657611aa6611a22565b500290565b60008219821115611abe57611abe611a22565b500190565b60018060a01b0384168152826020820152606060408201526000611aea60608301846119d4565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0383168152604060208201819052600090611b2d908301846119d4565b949350505050565b600060208284031215611b4757600080fd5b5051919050565b600060208284031215611b6057600080fd5b815161103981611664565b634e487b7160e01b600052603160045260246000fdfea164736f6c634300080b000a
Verified Source Code Partial Match
Compiler: v0.8.11+commit.d7f03943
EVM: london
Optimization: Yes (200 runs)
IReceiver.sol 7 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
interface IReceiver {
function notify() external;
function configure() external;
}
Ownable.sol 76 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
IERC20.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)
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);
}
Address.sol 217 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
EnumerableSet.sol 357 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
return _values(set._inner);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
Inflation.sol 244 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interfaces/IMint.sol";
import "./interfaces/IReceiver.sol";
contract Inflation is Ownable {
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
address public immutable token;
uint256 public totalMinted;
uint256 public immutable targetMinted;
uint256 public immutable periodicEmission;
uint256 public immutable startInflationTime;
uint256 public lastTs;
uint256 public immutable periodDuration; // seconds
mapping(address => uint256) public weights; // in points relative to sumWeight
mapping(address => uint256) public available;
mapping(address => uint256) public claimed;
uint256 public toDistribute;
uint256 public constant sumWeight = 10000;
EnumerableSet.AddressSet internal receivers;
event ReceiverAdded(address receiver, uint256 weight, uint256[] oldWeights);
event ReceiverRemoved(address receiver, uint256[] newWeights);
event Reconfigured(uint256[] newWeights);
event TokenClaimed(address receiver);
// """
// @notice Contract constructor
// @param _name Token full name
// @param _symbol Token symbol
// @param _decimals Number of decimals for token
// @param _targetMinted max amount minted during
// """
constructor(
address _token,
uint256 _targetMinted,
uint256 _periodsCount,
uint256 _periodDuration
) {
token = _token;
targetMinted = _targetMinted;
periodicEmission = _targetMinted / _periodsCount;
periodDuration = _periodDuration;
require(periodDuration > 0, "periodDuration=0");
startInflationTime = block.timestamp;
}
// """
// @notice Current number of tokens in existence (claimed or unclaimed)
// """
function availableSupply() external view returns (uint256) {
return totalMinted;
}
function addReceiver(
address _newReceiver,
uint256 _weightForNew,
bool _callConfigureForNew,
uint256[] memory _weightsForOld,
bool[] memory _callConfigureForOld
)
external
onlyOwner
{
require(_weightsForOld.length == _callConfigureForOld.length && _weightsForOld.length == receivers.length(), "lengths !equal");
require(_weightForNew > 0, "incorrect weight");
_mint();
require(!receivers.contains(_newReceiver), "already added");
uint256 sum = _reconfigure(_weightsForOld, _callConfigureForOld);
sum += _weightForNew;
require(sum == 10000, "incorrect sum");
receivers.add(_newReceiver);
weights[_newReceiver] = _weightForNew;
if (_newReceiver.isContract() && _callConfigureForNew) IReceiver(_newReceiver).configure();
emit ReceiverAdded(_newReceiver, _weightForNew, _weightsForOld);
}
function reconfigureReceivers(
uint256[] memory _weights,
bool[] memory _callConfigureForNew
) onlyOwner external {
_mint();
require(_weights.length == _callConfigureForNew.length && _weights.length == receivers.length(), "lengths !equal");
uint256 sum = _reconfigure(_weights, _callConfigureForNew);
require(sum == 10000, "incorrect sum");
emit Reconfigured(_weights);
}
function removeReceiver(
address _receiver,
bool _callConfigure,
uint256[] memory _newWeights,
bool[] memory _newCallConfigure
) onlyOwner external {
require(_newWeights.length == _newCallConfigure.length && _newWeights.length == receivers.length() - 1, "lengths !equal");
_mint();
uint256 amountToDistribute = toDistribute;
for (uint256 i; i < receivers.length(); i++) {
address receiver = receivers.at(i);
available[receiver] = amountToDistribute * weights[receiver] / sumWeight + available[receiver];
}
toDistribute = 0;
receivers.remove(_receiver);
delete weights[_receiver];
uint256 sum = _reconfigure(_newWeights, _newCallConfigure);
if (_receiver.isContract() && _callConfigure) IReceiver(_receiver).configure();
require(sum == 10000, "incorrect sum");
emit ReceiverRemoved(_receiver, _newWeights);
}
function _reconfigure(
uint256[] memory _weights,
bool[] memory _callConfigureForNew
) internal returns(uint256){
uint256 sum;
uint256 _amountToDistribute = toDistribute;
for (uint256 i; i < _weights.length; i++) {
require(_weights[i] > 0, "incorrect weight");
sum += _weights[i];
address receiver = receivers.at(i);
available[receiver] = _amountToDistribute * weights[receiver] / sumWeight + available[receiver] - claimed[receiver];
claimed[receiver] = 0;
weights[receiver] = _weights[i];
if (receiver.isContract() && _callConfigureForNew[i]) IReceiver(receiver).configure();
}
toDistribute = 0;
return sum;
}
function getToken(address _account) external {
_mint();
_getToken(_account, IERC20(token));
}
function getToken(address[] memory _accounts) external {
_mint();
IERC20 token_ = IERC20(token);
for (uint256 i; i < _accounts.length; i++) {
_getToken(_accounts[i], token_);
}
}
function getToken() external {
_mint();
IERC20 token_ = IERC20(token);
for (uint256 i; i < receivers.length(); i++) {
_getToken(receivers.at(i), token_);
}
}
function _getToken(address _account, IERC20 _token) internal {
uint256 toDistributeMember = toDistribute * weights[_account] / sumWeight;
uint256 pendingReward = toDistributeMember + available[_account] - claimed[_account];
claimed[_account] += toDistributeMember - claimed[_account];
available[_account] = 0;
if (pendingReward > 0) {
_safeTransfer(_account, pendingReward);
emit TokenClaimed(_account);
}
}
function receiversCount() external view returns (uint256) {
return receivers.length();
}
function receiverAt(uint256 index) external view returns (address) {
return receivers.at(index);
}
function getAllReceivers() external view returns (address[] memory) {
uint256 length = receivers.length();
address[] memory receivers_ = new address[](length);
for (uint256 i; i < length; i++) {
receivers_[i] = receivers.at(i);
}
return receivers_;
}
function _getPeriodsPassed() internal view returns (uint256) {
return (block.timestamp - startInflationTime) / periodDuration;
}
function claimable(address _receiver) public view returns(uint256) {
uint256 total = totalMinted;
uint256 target = targetMinted;
uint256 dtMember = (block.timestamp - lastTs) / periodDuration * periodicEmission;
if (dtMember + total > target) dtMember = target - total;
uint256 dynamicMember = receivers.contains(_receiver) ? (dtMember + toDistribute) * weights[_receiver] / sumWeight : 0;
return dynamicMember + available[_receiver] - claimed[_receiver];
}
function _safeTransfer(address _to, uint256 _amount) internal {
address token_ = token;
uint256 balance = IERC20(token_).balanceOf(address(this));
if (balance >= _amount) {
IERC20(token_).transfer(_to, _amount);
} else {
IERC20(token_).transfer(_to, balance);
}
}
// """
// @notice Mint part of available supply of tokens and assign them to approved contracts
// @dev Emits a Transfer event originating from 0x00
// @return bool success
// """
function _mint() internal returns (uint256){
uint256 total = totalMinted;
uint256 target = targetMinted;
uint256 amountToPay;
if(total < target && receivers.length() != 0) {
// distribute prepaid amount for the upfront period
uint256 periodsToPay = _getPeriodsPassed();
// if we missed a payment, the amount will be multiplied
uint256 mintForPeriods = periodsToPay * periodicEmission;
uint256 plannedToMint = mintForPeriods > target ? target : mintForPeriods;
amountToPay = plannedToMint - total;
totalMinted += amountToPay;
IMint(token).mint(address(this), amountToPay);
lastTs = block.timestamp;
}
toDistribute += amountToPay;
return amountToPay;
}
}
IMint.sol 6 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
interface IMint {
function mint(address account, uint256 amount) external;
}
Read Contract
available 0x10098ad5 → uint256
availableSupply 0x7ecc2b56 → uint256
claimable 0x402914f5 → uint256
claimed 0xc884ef83 → uint256
getAllReceivers 0xc1cc7010 → address[]
lastTs 0x4e4f8289 → uint256
owner 0x8da5cb5b → address
periodDuration 0xb470aade → uint256
periodicEmission 0xdbe62545 → uint256
receiverAt 0x477d566b → address
receiversCount 0x360ed9c2 → uint256
startInflationTime 0x851f1d9e → uint256
sumWeight 0xb23ac410 → uint256
targetMinted 0x3b5bf85d → uint256
toDistribute 0x5311135e → uint256
token 0xfc0c546a → address
totalMinted 0xa2309ff8 → uint256
weights 0xa7cac846 → uint256
Write Contract 8 functions
These functions modify contract state and require a wallet transaction to execute.
addReceiver 0x766a4afb
address _newReceiver
uint256 _weightForNew
bool _callConfigureForNew
uint256[] _weightsForOld
bool[] _callConfigureForOld
getToken 0x21df0da7
No parameters
getToken 0x59770438
address _account
getToken 0xab39f828
address[] _accounts
reconfigureReceivers 0x19039e89
uint256[] _weights
bool[] _callConfigureForNew
removeReceiver 0xe5d7ac08
address _receiver
bool _callConfigure
uint256[] _newWeights
bool[] _newCallConfigure
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address