Address Contract Verified
Address
0x7FA0eDB4F1ceF0011e2C219182fb4C30f3C012dc
Balance
0 ETH
Nonce
1
Code Size
7682 bytes
Creator
0x2Ffc59d3...33C0 at tx 0x4e64ab2c...b8f5df
Indexed Transactions
0
Contract Bytecode
7682 bytes
0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806357f0a2321161008c578063bdfdd38311610066578063bdfdd3831461018f578063c395b791146101a2578063f88e0d7a146101b5578063fea85606146101c857600080fd5b806357f0a232146101565780635abdb0dc1461016957806364a3b9de1461017c57600080fd5b806314e1b8fd146100d4578063271ec305146100eb5780632e1a7d4d146100f35780633be894c714610108578063477348921461011b578063485cc95514610143575b600080fd5b6038545b6040519081526020015b60405180910390f35b6037546100d8565b610106610101366004611712565b6101db565b005b610106610116366004611747565b6102c7565b61012e610129366004611794565b61035d565b604080519283526020830191909152016100e2565b6101066101513660046117b8565b6103d7565b610106610164366004611712565b6104d0565b610106610177366004611712565b6105f5565b61010661018a3660046117f1565b61072c565b61010661019d366004611882565b6107c3565b6101066101b036600461191b565b61094b565b6101066101c3366004611712565b610a6a565b6101066101d6366004611986565b610b78565b6002600154036102065760405162461bcd60e51b81526004016101fd906119c7565b60405180910390fd5b600260015560385481101561025d5760405162461bcd60e51b815260206004820152601a60248201527f5061794173596f75476f3a20616d6f756e7420746f6f206c6f7700000000000060448201526064016101fd565b61026b6305f5e10082611a14565b156102885760405162461bcd60e51b81526004016101fd90611a28565b61029966038d7ea4c6800082611a14565b156102b65760405162461bcd60e51b81526004016101fd90611a6c565b6102c03382610db5565b5060018055565b6002600154036102e95760405162461bcd60e51b81526004016101fd906119c7565b60026001556102fc6305f5e10084611a14565b156103195760405162461bcd60e51b81526004016101fd90611a28565b61032a66038d7ea4c6800084611a14565b156103475760405162461bcd60e51b81526004016101fd90611a6c565b6103543384843385610f6d565b50506001805550565b6001600160a01b03811660009081526035602090815260408083208151808301909252546001600160501b03808216808452600160501b909204169282019290925282916103b0906305f5e10090611ab9565b6305f5e10082602001516001600160501b03166103cd9190611ab9565b9250925050915091565b600054610100900460ff166103f25760005460ff16156103f6565b303b155b6104595760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101fd565b600054610100900460ff1615801561047b576000805461ffff19166101011790555b61048361119b565b6104b98383603380546001600160a01b039283166001600160a01b03199182161790915560348054939092169216919091179055565b80156104cb576000805461ff00191690555b505050565b603460009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa158015610523573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105479190611ad8565b6001600160a01b0316336001600160a01b0316146105a75760405162461bcd60e51b815260206004820152601b60248201527f5061794173596f75476f3a206f6e6c7920676f7665726e616e6365000000000060448201526064016101fd565b80603760008282546105b99190611af5565b90915550506040518181527f39b5745de4157f6eed5f7018501052173ab2dfc60ed21bfb95aff2dd16a0819b906020015b60405180910390a150565b603460009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa158015610648573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066c9190611ad8565b6001600160a01b0316336001600160a01b0316146106cc5760405162461bcd60e51b815260206004820152601b60248201527f5061794173596f75476f3a206f6e6c7920676f7665726e616e6365000000000060448201526064016101fd565b6106da6305f5e10082611a14565b156106f75760405162461bcd60e51b81526004016101fd90611a28565b60388190556040518181527f755134315a797bb3da2a1dd9a4fe4183310c83d99e9b32ca94eb17d356a083e6906020016105ea565b60026001540361074e5760405162461bcd60e51b81526004016101fd906119c7565b60026001556107616305f5e10085611a14565b1561077e5760405162461bcd60e51b81526004016101fd90611a28565b61078f66038d7ea4c6800085611a14565b156107ac5760405162461bcd60e51b81526004016101fd90611a6c565b6107b93385858585610f6d565b5050600180555050565b603460009054906101000a90046001600160a01b03166001600160a01b031663dddce8c16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083a9190611ad8565b6001600160a01b0316336001600160a01b03161461086a5760405162461bcd60e51b81526004016101fd90611b0c565b848314801561087857508281145b6108c45760405162461bcd60e51b815260206004820152601a60248201527f5061794173596f75476f3a20636f72727570746564206461746100000000000060448201526064016101fd565b60005b85811015610942576109308787838181106108e4576108e4611b43565b90506020020160208101906108f99190611794565b86868481811061090b5761090b611b43565b9050602002013585858581811061092457610924611b43565b905060200201356111cc565b8061093a81611b59565b9150506108c7565b50505050505050565b603460009054906101000a90046001600160a01b03166001600160a01b031663dddce8c16040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c29190611ad8565b6001600160a01b0316336001600160a01b0316146109f25760405162461bcd60e51b81526004016101fd90611b0c565b8281146109fe57600080fd5b60005b83811015610a6357610a51858583818110610a1e57610a1e611b43565b9050602002016020810190610a339190611794565b848484818110610a4557610a45611b43565b9050602002013561145c565b80610a5b81611b59565b915050610a01565b5050505050565b6033546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae59190611b72565b610b315760405162461bcd60e51b815260206004820152601d60248201527f5061794173596f476f3a206661696c656420746f207472616e7366657200000060448201526064016101fd565b8060376000828254610b439190611b94565b90915550506040518181527f2b8e6e53758c5cf2af2b48ffaa0bfae269605ae293aed8a160dd245f18dc1724906020016105ea565b603460009054906101000a90046001600160a01b03166001600160a01b031663dddce8c16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bef9190611ad8565b6001600160a01b0316336001600160a01b031614610c1f5760405162461bcd60e51b81526004016101fd90611b0c565b603754811115610c715760405162461bcd60e51b815260206004820152601c60248201527f5061794173596f75476f3a20696e73756666696369656e74206665650000000060448201526064016101fd565b8060376000828254610c839190611af5565b909155505060335460405163095ea7b360e01b81526001600160a01b038581166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af1158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190611b72565b610d575760405162461bcd60e51b8152602060048201526024808201527f5061794173596f75476f3a2063616e277420696e63726561736520616c6c6f77604482015263616e636560e01b60648201526084016101fd565b60405163a8031a1d60e01b81526001600160a01b0383811660048301526024820183905284169063a8031a1d90604401600060405180830381600087803b158015610da157600080fd5b505af1158015610942573d6000803e3d6000fd5b6000610dc56305f5e10083611bac565b6001600160a01b0384166000908152603560209081526040918290208251808401909352546001600160501b03808216808552600160501b90920481169284019290925292935090919083161115610e2f5760405162461bcd60e51b81526004016101fd90611bc0565b60208101516001600160501b031615610e9e5760405162461bcd60e51b815260206004820152602b60248201527f5061794173596f75476f3a20616c726561647920686176652070656e64696e6760448201526a081dda5d1a191c985dd85b60aa1b60648201526084016101fd565b8181600001818151610eb09190611bf5565b6001600160501b0316905250602081018051839190610ed0908390611c1d565b6001600160501b039081169091526001600160a01b038616600081815260356020908152604080832087518154898501519188166001600160a01b031990911617600160501b91909716029590951790945583516024810193909352604480840189905284518085039091018152606490930190935291810180516001600160e01b031663da95ebf760e01b1790529150610a63908690836115ef565b831561103c576033546040516323b872dd60e01b81526001600160a01b03878116600483015230602483015260448201879052909116906323b872dd906064016020604051808303816000875af1158015610fcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff09190611b72565b61103c5760405162461bcd60e51b815260206004820152601a60248201527f5061794173596f75476f3a2063616e2774207472616e7366657200000000000060448201526064016101fd565b6001600160a01b0382166000908152603560209081526040918290208251808401909352546001600160501b038082168452600160501b90910416908201526110896305f5e10086611bac565b81518290611098908390611c1d565b6001600160501b039081169091526001600160a01b03851660008181526035602090815260409182902086518154888401518716600160501b026001600160a01b0319909116919096161794909417909355518881529092507f1423e2a671bcc71c56f3c3cb78e3c96473d3ca5eb061acd0b93d1d0a6617f658910160405180910390a26001600160a01b0383167e51293d38e656463ef897127472352b7fe9bd81b95264f5a53529012203e6a48660008061115d6001600160401b038a1642611b94565b6040805194855260ff9093166020850152918301526001600160401b031660608201526080810185905260a0015b60405180910390a2505050505050565b600054610100900460ff166111c25760405162461bcd60e51b81526004016101fd90611c48565b6111ca6116e5565b565b60006111dc6305f5e10084611bac565b905060006111ee6305f5e10084611bac565b6001600160a01b0386166000908152603560209081526040918290208251808401909352546001600160501b038082168452600160501b909104811691830182905292935090918416111561128f5760405162461bcd60e51b815260206004820152602160248201527f5061794173596f75476f3a2077726f6e6720776974686472617720616d6f756e6044820152601d60fa1b60648201526084016101fd565b6112998284611c1d565b6001600160501b0316816000015182602001516112b69190611c1d565b6001600160501b031610156112dd5760405162461bcd60e51b81526004016101fd90611bc0565b8281602001516112ed9190611bf5565b815182906112fc908390611c1d565b6001600160501b03908116909152600060208085018281526001600160a01b038b168352603590915260409091208451815492518416600160501b026001600160a01b031990931693169290921717905550831561135e5761135e868561145c565b60335460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018890529091169063a9059cbb906044016020604051808303816000875af11580156113b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d59190611b72565b6114215760405162461bcd60e51b815260206004820152601a60248201527f5061794173596f75476f3a2063616e2774207472616e7366657200000000000060448201526064016101fd565b856001600160a01b03167f7e187bf56d23cc278139f36660c1b9c56739b0518009319e389d2c33f7acc7d38660405161118b91815260200190565b600061146c6305f5e10083611bac565b6001600160a01b0384166000908152603560209081526040918290208251808401909352546001600160501b03808216808552600160501b909204811692840183905293945091928416916114c091611c1d565b6001600160501b031610156114e75760405162461bcd60e51b81526004016101fd90611bc0565b80516001600160501b0380841691161061151e57818160000181815161150d9190611bf5565b6001600160501b031690525061154c565b805161152a9083611bf5565b8160200181815161153b9190611bf5565b6001600160501b0316905250600081525b6001600160a01b0384166000908152603560209081526040822083518154928501516001600160501b03908116600160501b026001600160a01b0319909416911617919091179055603780548592906115a6908490611b94565b90915550506040518381526001600160a01b038516907f55bb3cade9d43b798a4fe5ffdd05024b2d7870df53920673bfc7e68047cd0ab19060200160405180910390a250505050565b6001600160a01b038316600090815260366020526040812080546001600160401b03169182919061161f83611c93565b91906101000a8154816001600160401b0302191690836001600160401b031602179055505060008482468560405160200161165d9493929190611ce9565b604051602081830303815290604052805190602001209050836001600160401b031660000361168d5762093a8093505b60006116998542611d3e565b90507f9cedd81d22046b444fae1c859e320d9588a863927132b4774ddd494cdc7380b9828760003088866040516116d596959493929190611d60565b60405180910390a1505050505050565b600054610100900460ff1661170c5760405162461bcd60e51b81526004016101fd90611c48565b60018055565b60006020828403121561172457600080fd5b5035919050565b80356001600160401b038116811461174257600080fd5b919050565b60008060006060848603121561175c57600080fd5b8335925061176c6020850161172b565b9150604084013590509250925092565b6001600160a01b038116811461179157600080fd5b50565b6000602082840312156117a657600080fd5b81356117b18161177c565b9392505050565b600080604083850312156117cb57600080fd5b82356117d68161177c565b915060208301356117e68161177c565b809150509250929050565b6000806000806080858703121561180757600080fd5b843593506118176020860161172b565b925060408501356118278161177c565b9396929550929360600135925050565b60008083601f84011261184957600080fd5b5081356001600160401b0381111561186057600080fd5b6020830191508360208260051b850101111561187b57600080fd5b9250929050565b6000806000806000806060878903121561189b57600080fd5b86356001600160401b03808211156118b257600080fd5b6118be8a838b01611837565b909850965060208901359150808211156118d757600080fd5b6118e38a838b01611837565b909650945060408901359150808211156118fc57600080fd5b5061190989828a01611837565b979a9699509497509295939492505050565b6000806000806040858703121561193157600080fd5b84356001600160401b038082111561194857600080fd5b61195488838901611837565b9096509450602087013591508082111561196d57600080fd5b5061197a87828801611837565b95989497509550505050565b60008060006060848603121561199b57600080fd5b83356119a68161177c565b925060208401356119b68161177c565b929592945050506040919091013590565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601260045260246000fd5b600082611a2357611a236119fe565b500690565b60208082526024908201527f5061794173596f75476f3a2072656d61696e646572206973206e6f7420616c6c6040820152631bddd95960e21b606082015260800190565b6020808252601e908201527f5061794173596f75476f3a20746f6f206869676820707265636973696f6e0000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615611ad357611ad3611aa3565b500290565b600060208284031215611aea57600080fd5b81516117b18161177c565b600082821015611b0757611b07611aa3565b500390565b6020808252601a908201527f5061794173596f75476f3a206f6e6c7920636f6e73656e737573000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060018201611b6b57611b6b611aa3565b5060010190565b600060208284031215611b8457600080fd5b815180151581146117b157600080fd5b60008219821115611ba757611ba7611aa3565b500190565b600082611bbb57611bbb6119fe565b500490565b6020808252818101527f5061794173596f75476f3a20696e73756666696369656e742062616c616e6365604082015260600190565b60006001600160501b0383811690831681811015611c1557611c15611aa3565b039392505050565b60006001600160501b03808316818516808303821115611c3f57611c3f611aa3565b01949350505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160401b03808316818103611caf57611caf611aa3565b6001019392505050565b60005b83811015611cd4578181015183820152602001611cbc565b83811115611ce3576000848401525b50505050565b6bffffffffffffffffffffffff198560601b1681526001600160401b0360c01b8460c01b16601482015282601c82015260008251611d2e81603c850160208701611cb9565b91909101603c0195945050505050565b60006001600160401b03808316818516808303821115611c3f57611c3f611aa3565b868152600060018060a01b03808816602084015286604084015280861660608401525060c0608083015283518060c0840152611da38160e0850160208801611cb9565b6001600160401b039390931660a083015250601f91909101601f19160160e0019594505050505056fea2646970667358221220b2fb8d46715ff7c39235fcf86704440c0c7ea06a56094b225fae2aadf25debeb64736f6c634300080e0033
Verified Source Code Full Match
Compiler: v0.8.14+commit.80d49f37
EVM: london
Optimization: Yes (200 runs)
IAnkrProtocol.sol 43 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.7;
interface IAnkrProtocol {
// tier lifecycle events
event TierLevelCreated(uint8 level);
event TierLevelChanged(uint8 level);
event TierLevelRemoved(uint8 level);
// jwt token issue
event TierAssigned(address indexed sender, uint256 amount, uint8 tier, uint256 roles, uint64 expires, bytes32 publicKey);
// balance management
event FundsLocked(address indexed sender, uint256 amount);
event FundsUnlocked(address indexed sender, uint256 amount);
event FeeCharged(address indexed sender, uint256 fee);
function deposit(uint256 amount, uint64 timeout, bytes32 publicKey) external;
function withdraw(uint256 amount) external;
}
interface IRequestFormat {
function requestWithdrawal(address sender, uint256 amount) external;
}
interface ITransportLayer {
event ProviderRequest(
bytes32 id,
address sender,
uint256 fee,
address callback,
bytes data,
uint64 expires
);
function handleChargeFee(address[] calldata users, uint256[] calldata fees) external;
function handleWithdraw(address[] calldata users, uint256[] calldata amounts, uint256[] calldata fees) external;
}
IERC20.sol 30 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.7;
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
interface IERC20Mintable {
function mint(address account, uint256 amount) external;
function burn(address account, uint256 amount) external;
}
interface IERC20Extra {
function name() external returns (string memory);
function decimals() external returns (uint8);
function symbol() external returns (string memory);
}
interface IERC20Pegged {
function getOrigin() external view returns (uint256, address);
}
interface IERC20InternetBond {
function ratio() external view returns (uint256);
}
IGovernable.sol 7 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.7;
interface IGovernable {
function getGovernanceAddress() external view returns (address);
}
IStaking.sol 90 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.7;
import "./IStakingConfig.sol";
interface IStaking {
function getStakingConfig() external view returns (IStakingConfig);
function getValidators() external view returns (address[] memory);
function isValidatorActive(address validator) external view returns (bool);
function isValidator(address validator) external view returns (bool);
function getValidatorStatus(address validator) external view returns (
address ownerAddress,
uint8 status,
uint256 totalDelegated,
uint32 slashesCount,
uint64 changedAt,
uint64 jailedBefore,
uint64 claimedAt,
uint16 commissionRate,
uint96 totalRewards
);
function getValidatorStatusAtEpoch(address validator, uint64 epoch) external view returns (
address ownerAddress,
uint8 status,
uint256 totalDelegated,
uint32 slashesCount,
uint64 changedAt,
uint64 jailedBefore,
uint64 claimedAt,
uint16 commissionRate,
uint96 totalRewards
);
function getValidatorByOwner(address owner) external view returns (address);
function registerValidator(address validator, uint16 commissionRate) payable external;
function addValidator(address validator) external;
function removeValidator(address validator) external;
function activateValidator(address validator) external;
function disableValidator(address validator) external;
function releaseValidatorFromJail(address validator) external;
function changeValidatorCommissionRate(address validator, uint16 commissionRate) external;
function changeValidatorOwner(address validator, address newOwner) external;
function getValidatorDelegation(address validator, address delegator) external view returns (
uint256 delegatedAmount,
uint64 atEpoch
);
function delegate(address validator, uint256 amount) payable external;
function undelegate(address validator, uint256 amount) external;
function getValidatorFee(address validator) external view returns (uint256);
function getPendingValidatorFee(address validator) external view returns (uint256);
function claimValidatorFee(address validator) external;
function getDelegatorFee(address validator, address delegator) external view returns (uint256);
function getPendingDelegatorFee(address validator, address delegator) external view returns (uint256);
function claimDelegatorFee(address validator) external;
function claimStakingRewards(address validatorAddress) external;
function claimPendingUndelegates(address validator) external;
function calcAvailableForRedelegateAmount(address validator, address delegator) external view returns (uint256 amountToStake, uint256 rewardsDust);
function redelegateDelegatorFee(address validator) external;
function currentEpoch() external view returns (uint64);
function nextEpoch() external view returns (uint64);
}
ContextUpgradeable.sol 37 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @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 ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
IERC20.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
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);
}
ITokenStaking.sol 13 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IStaking.sol";
interface ITokenStaking is IStaking {
function getErc20Token() external view returns (IERC20);
function distributeRewards(address validatorAddress, uint256 amount) external;
}
IEarnConfig.sol 29 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.7;
import "./IGovernable.sol";
interface IEarnConfig is IGovernable {
function getConsensusAddress() external view returns (address);
function setConsensusAddress(address newValue) external;
function getGovernanceAddress() external view override returns (address);
function setGovernanceAddress(address newValue) external;
function getTreasuryAddress() external view returns (address);
function setTreasuryAddress(address newValue) external;
function getSwapFeeRatio() external view returns (uint16);
function setSwapFeeRatio(uint16 newValue) external;
function pauseBondStaking() external;
function unpauseBondStaking() external;
function isBondStakingPaused() external view returns (bool);
}
OwnableUpgradeable.sol 88 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_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);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
PayAsYouGo.sol 223 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.7;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import "../interfaces/IAnkrProtocol.sol";
import "../interfaces/IERC20.sol";
import "../interfaces/IStakingConfig.sol";
import "../interfaces/IEarnConfig.sol";
import "../interfaces/ITokenStaking.sol";
contract PayAsYouGo is ReentrancyGuardUpgradeable, IAnkrProtocol, ITransportLayer {
uint256 internal constant BALANCE_COMPACT_PRECISION = 1e8;
uint256 internal constant DEPOSIT_WITHDRAW_PRECISION = 1e15;
event MinWithdrawAmountSet(uint256 amount);
event InstantlyChargeCollectedFee(uint256 amount);
event ManuallyFeedCollectedFee(uint256 amount);
struct UserBalance {
uint80 available;
uint80 pending;
}
IERC20Upgradeable internal _ankrToken;
IEarnConfig internal _earnConfig;
mapping(address => UserBalance) internal _userDeposits;
mapping(address => uint64) internal _requestNonce;
uint256 internal _collectedFee;
uint256 internal _minWithdrawAmount;
function initialize(IEarnConfig earnConfig, IERC20Upgradeable ankrToken) external initializer {
__ReentrancyGuard_init();
__AnkrProtocol_init(earnConfig, ankrToken);
}
function __AnkrProtocol_init(IEarnConfig earnConfig, IERC20Upgradeable ankrToken) internal {
_ankrToken = ankrToken;
_earnConfig = earnConfig;
}
modifier onlyGovernance() {
require(msg.sender == address(_earnConfig.getGovernanceAddress()), "PayAsYouGo: only governance");
_;
}
modifier onlyConsensus() {
require(msg.sender == address(_earnConfig.getConsensusAddress()), "PayAsYouGo: only consensus");
_;
}
modifier onlyTreasury() {
require(msg.sender == address(_earnConfig.getTreasuryAddress()), "PayAsYouGo: only treasury");
_;
}
function getUserBalance(address user) external view returns (
uint256 available,
uint256 pending
) {
UserBalance memory userDeposit = _userDeposits[user];
return (
uint256(userDeposit.available) * BALANCE_COMPACT_PRECISION,
uint256(userDeposit.pending) * BALANCE_COMPACT_PRECISION
);
}
function deposit(uint256 amount, uint64 timeout, bytes32 publicKey) external nonReentrant override {
require(amount % BALANCE_COMPACT_PRECISION == 0, "PayAsYouGo: remainder is not allowed");
require(amount % DEPOSIT_WITHDRAW_PRECISION == 0, "PayAsYouGo: too high precision");
_lockDepositForUser(msg.sender, amount, timeout, msg.sender, publicKey);
}
function depositForUser(uint256 amount, uint64 timeout, address user, bytes32 publicKey) external nonReentrant {
require(amount % BALANCE_COMPACT_PRECISION == 0, "PayAsYouGo: remainder is not allowed");
require(amount % DEPOSIT_WITHDRAW_PRECISION == 0, "PayAsYouGo: too high precision");
_lockDepositForUser(msg.sender, amount, timeout, user, publicKey);
}
// function _lockDeposit(address sender, uint256 amount, uint64 timeout, bytes32 publicKey) internal {
// if (amount > 0) {
// require(_ankrToken.transferFrom(msg.sender, address(this), amount), "PayAsYouGo: can't transfer");
// }
// // obtain user's lock and match next tier level
// UserBalance memory userDeposit = _userDeposits[sender];
// userDeposit.available += uint80(amount / BALANCE_COMPACT_PRECISION);
// _userDeposits[sender] = userDeposit;
// emit FundsLocked(sender, amount);
// // emit event for JWT token
// emit TierAssigned(sender, amount, 0, 0, uint64(block.timestamp + timeout), publicKey);
// }
function _lockDepositForUser(address sender, uint256 amount, uint64 timeout, address user, bytes32 publicKey) internal {
if (amount > 0) {
require(_ankrToken.transferFrom(sender, address(this), amount), "PayAsYouGo: can't transfer");
}
// obtain user's lock and match next tier level
UserBalance memory userDeposit = _userDeposits[user];
userDeposit.available += uint80(amount / BALANCE_COMPACT_PRECISION);
_userDeposits[user] = userDeposit;
emit FundsLocked(user, amount);
// emit event for JWT token
emit TierAssigned(user, amount, 0, 0, uint64(block.timestamp + timeout), publicKey);
}
function withdraw(uint256 amount) external nonReentrant override {
require(amount >= _minWithdrawAmount, "PayAsYouGo: amount too low");
require(amount % BALANCE_COMPACT_PRECISION == 0, "PayAsYouGo: remainder is not allowed");
require(amount % DEPOSIT_WITHDRAW_PRECISION == 0, "PayAsYouGo: too high precision");
_createWithdrawal(msg.sender, amount);
}
function _createWithdrawal(address sender, uint256 amount) internal {
uint80 amount80 = uint80(amount / BALANCE_COMPACT_PRECISION);
UserBalance memory userDeposit = _userDeposits[sender];
require(userDeposit.available >= amount80, "PayAsYouGo: insufficient balance");
require(userDeposit.pending == 0, "PayAsYouGo: already have pending withdrawal");
userDeposit.available -= amount80;
userDeposit.pending += amount80;
_userDeposits[sender] = userDeposit;
// trigger withdraw request
bytes memory input = abi.encodeWithSelector(IRequestFormat.requestWithdrawal.selector, sender, amount);
_triggerRequestEvent(sender, 0, input);
}
function handleChargeFee(address[] calldata users, uint256[] calldata fees) external onlyConsensus override {
require(users.length == fees.length);
for (uint256 i = 0; i < users.length; i++) {
_chargeAnkrFor(users[i], fees[i]);
}
}
function _chargeAnkrFor(address sender, uint256 fee) internal {
uint80 fee80 = uint80(fee / BALANCE_COMPACT_PRECISION);
UserBalance memory userDeposit = _userDeposits[sender];
require((userDeposit.pending + userDeposit.available) >= fee80, "PayAsYouGo: insufficient balance");
if (userDeposit.available >= fee80) {
userDeposit.available -= fee80;
} else {
userDeposit.pending -= (fee80 - userDeposit.available);
userDeposit.available = 0;
}
_userDeposits[sender] = userDeposit;
_collectedFee += fee;
emit FeeCharged(sender, fee);
}
function handleWithdraw(address[] calldata users, uint256[] calldata amounts, uint256[] calldata fees) external onlyConsensus override {
require(users.length == amounts.length && amounts.length == fees.length, "PayAsYouGo: corrupted data");
for (uint256 i = 0; i < users.length; i++) {
_doWithdraw(users[i], amounts[i], fees[i]);
}
}
function _doWithdraw(address user, uint256 amount, uint256 fee) internal {
uint80 amount80 = uint80(amount / BALANCE_COMPACT_PRECISION);
uint80 fee80 = uint80(fee / BALANCE_COMPACT_PRECISION);
// decrease user's balance
UserBalance memory userDeposit = _userDeposits[user];
require(userDeposit.pending >= amount80, "PayAsYouGo: wrong withdraw amount");
require((userDeposit.pending + userDeposit.available) >= (amount80 + fee80), "PayAsYouGo: insufficient balance");
userDeposit.available += userDeposit.pending - amount80;
userDeposit.pending = 0;
_userDeposits[user] = userDeposit;
// if we have specified fee then charge it from user's account
if (fee > 0) {
_chargeAnkrFor(user, fee);
}
// transfer funds to user
require(_ankrToken.transfer(user, amount), "PayAsYouGo: can't transfer");
// emit event
emit FundsUnlocked(user, amount);
}
function _triggerRequestEvent(address sender, uint64 lifetime, bytes memory input) internal {
// increase nonce
uint64 nonce = _requestNonce[sender];
_requestNonce[sender]++;
// calc request id
bytes32 id = keccak256(abi.encodePacked(sender, nonce, block.chainid, input));
// request expiration time (default lifetime is 1 week)
if (lifetime == 0) {
lifetime = 604800;
}
uint64 expires = uint64(block.timestamp) + lifetime;
// emit as event to provider
emit ProviderRequest(id, sender, 0, address(this), input, expires);
}
function setMinWithdrawAmount(uint256 minWithdrawalAmount) external onlyGovernance {
require(minWithdrawalAmount % BALANCE_COMPACT_PRECISION == 0, "PayAsYouGo: remainder is not allowed");
_minWithdrawAmount = minWithdrawalAmount;
emit MinWithdrawAmountSet(minWithdrawalAmount);
}
function getMinWithdrawAmount() external view returns (uint256) {
return _minWithdrawAmount;
}
function getCollectedFee() external view returns (uint256) {
return _collectedFee;
}
function instantlyChargeCollectedFee(uint256 amount) external onlyGovernance {
_collectedFee -= amount;
emit InstantlyChargeCollectedFee(amount);
}
function manuallyFeedCollectedFee(uint256 amount) external {
require(_ankrToken.transferFrom(msg.sender, address(this), amount), "PayAsYoGo: failed to transfer");
_collectedFee += amount;
emit ManuallyFeedCollectedFee(amount);
}
function deliverReward(address stakingContract, address validatorAddress, uint256 amount) external onlyConsensus {
require(amount <= _collectedFee, "PayAsYouGo: insufficient fee");
_collectedFee -= amount;
require(_ankrToken.approve(stakingContract, amount), "PayAsYouGo: can't increase allowance");
ITokenStaking(stakingContract).distributeRewards(validatorAddress, amount);
}
}
Initializable.sol 80 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.0;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
* initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() initializer {}
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
// If the contract is initializing we ignore whether _initialized is set in order to support multiple
// inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
// contract may have been reentered.
require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} modifier, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
function _isConstructor() private view returns (bool) {
return !AddressUpgradeable.isContract(address(this));
}
}
ReentrancyGuardUpgradeable.sol 75 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
IERC20Upgradeable.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20Upgradeable {
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
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);
}
AddressUpgradeable.sol 195 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @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
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 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 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);
}
}
}
}
IStakingConfig.sol 51 lines
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.7;
import "./IGovernable.sol";
interface IStakingConfig is IGovernable {
function getActiveValidatorsLength() external view returns (uint32);
function setActiveValidatorsLength(uint32 newValue) external;
function getEpochBlockInterval() external view returns (uint32);
function setEpochBlockInterval(uint32 newValue) external;
function getMisdemeanorThreshold() external view returns (uint32);
function setMisdemeanorThreshold(uint32 newValue) external;
function getFelonyThreshold() external view returns (uint32);
function setFelonyThreshold(uint32 newValue) external;
function getValidatorJailEpochLength() external view returns (uint32);
function setValidatorJailEpochLength(uint32 newValue) external;
function getUndelegatePeriod() external view returns (uint32);
function setUndelegatePeriod(uint32 newValue) external;
function getMinValidatorStakeAmount() external view returns (uint256);
function setMinValidatorStakeAmount(uint256 newValue) external;
function getMinStakingAmount() external view returns (uint256);
function setMinStakingAmount(uint256 newValue) external;
function getGovernanceAddress() external view override returns (address);
function setGovernanceAddress(address newValue) external;
function getTreasuryAddress() external view returns (address);
function setTreasuryAddress(address newValue) external;
function getLockPeriod() external view returns (uint64);
function setLockPeriod(uint64 newValue) external;
}
Read Contract
getCollectedFee 0x271ec305 → uint256
getMinWithdrawAmount 0x14e1b8fd → uint256
getUserBalance 0x47734892 → uint256, uint256
Write Contract 10 functions
These functions modify contract state and require a wallet transaction to execute.
deliverReward 0xfea85606
address stakingContract
address validatorAddress
uint256 amount
deposit 0x3be894c7
uint256 amount
uint64 timeout
bytes32 publicKey
depositForUser 0x64a3b9de
uint256 amount
uint64 timeout
address user
bytes32 publicKey
handleChargeFee 0xc395b791
address[] users
uint256[] fees
handleWithdraw 0xbdfdd383
address[] users
uint256[] amounts
uint256[] fees
initialize 0x485cc955
address earnConfig
address ankrToken
instantlyChargeCollectedFee 0x57f0a232
uint256 amount
manuallyFeedCollectedFee 0xf88e0d7a
uint256 amount
setMinWithdrawAmount 0x5abdb0dc
uint256 minWithdrawalAmount
withdraw 0x2e1a7d4d
uint256 amount
Recent Transactions
No transactions found for this address