Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Multi Chain
Multichain Addresses
1 address found via
Latest 25 from a total of 89 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Execute | 14372863 | 562 days 3 hrs ago | IN | 0 ETH | 0.00836383 | ||||
Execute | 14372860 | 562 days 3 hrs ago | IN | 0 ETH | 0.00964818 | ||||
Execute | 14372700 | 562 days 4 hrs ago | IN | 0 ETH | 0.00701709 | ||||
Execute | 14372554 | 562 days 5 hrs ago | IN | 0 ETH | 0.00642789 | ||||
Execute | 14372350 | 562 days 5 hrs ago | IN | 0 ETH | 0.00556276 | ||||
Execute | 14372259 | 562 days 6 hrs ago | IN | 0 ETH | 0.00647024 | ||||
Execute | 14372168 | 562 days 6 hrs ago | IN | 0 ETH | 0.00801931 | ||||
Execute | 14372100 | 562 days 6 hrs ago | IN | 0 ETH | 0.01309611 | ||||
Execute | 14372085 | 562 days 6 hrs ago | IN | 0 ETH | 0.00614765 | ||||
Execute | 14371972 | 562 days 7 hrs ago | IN | 0 ETH | 0.00646318 | ||||
Execute | 14371965 | 562 days 7 hrs ago | IN | 0 ETH | 0.00548943 | ||||
Execute | 14371959 | 562 days 7 hrs ago | IN | 0 ETH | 0.00405346 | ||||
Execute | 14371947 | 562 days 7 hrs ago | IN | 0 ETH | 0.00445303 | ||||
Execute | 14371669 | 562 days 8 hrs ago | IN | 0 ETH | 0.00471411 | ||||
Execute | 14371597 | 562 days 8 hrs ago | IN | 0 ETH | 0.00530762 | ||||
Execute | 14371142 | 562 days 10 hrs ago | IN | 0 ETH | 0.00382801 | ||||
Execute | 14370432 | 562 days 12 hrs ago | IN | 0 ETH | 0.00421574 | ||||
Execute | 14369577 | 562 days 16 hrs ago | IN | 0 ETH | 0.0044772 | ||||
Execute | 14369541 | 562 days 16 hrs ago | IN | 0 ETH | 0.00496861 | ||||
Execute | 14368145 | 562 days 21 hrs ago | IN | 0 ETH | 0.00920854 | ||||
Execute | 14367287 | 563 days 48 mins ago | IN | 0 ETH | 0.00639152 | ||||
Execute | 14366352 | 563 days 4 hrs ago | IN | 0 ETH | 0.02010585 | ||||
Execute | 14365850 | 563 days 6 hrs ago | IN | 0 ETH | 0.00471555 | ||||
Execute | 14363798 | 563 days 14 hrs ago | IN | 0 ETH | 0.00509178 | ||||
Execute | 14363760 | 563 days 14 hrs ago | IN | 0 ETH | 0.00684652 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
SherBuy
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 20000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '@openzeppelin/contracts/security/ReentrancyGuard.sol'; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import './interfaces/ISherClaim.sol'; import './interfaces/ISherlock.sol'; /// @title Buy SHER tokens by staking USDC and paying USDC /// @author Evert Kors /// @dev The goal is to get TVL in Sherlock.sol and raise funds with `receiver` /// @dev Bought SHER tokens are moved to a timelock contract (SherClaim) /// @dev Admin should send factor of 0.01 SHER tokens to the contract, otherwise logic will break. contract SherBuy is ReentrancyGuard { using SafeERC20 for IERC20; error InvalidSender(); error InvalidAmount(); error ZeroArgument(); error InvalidState(); error SoldOut(); /// @notice Emitted when SHER purchase is executed /// @param buyer Account that bought SHER tokens /// @param amount How much SHER tokens are bought /// @param staked How much USDC is staked /// @param paid How much USDC is paid event Purchase(address indexed buyer, uint256 amount, uint256 staked, uint256 paid); // The staking period used for the staking USDC uint256 public constant PERIOD = 26 weeks; // Allows purchases in steps of 0.01 SHER uint256 internal constant SHER_STEPS = 10**16; // Allows stakeRate and buyRate with steps of 0.01 USDC uint256 internal constant RATE_STEPS = 10**4; // SHER has 18 decimals uint256 internal constant SHER_DECIMALS = 10**18; // SHER token address (18 decimals) IERC20 public immutable sher; // USDC token address (6 decimals) IERC20 public immutable usdc; // 10**6 means for every 1 SHER token you want to buy, you will stake 1 USDC (10**7 means 1 SHER for 10 USDC) uint256 public immutable stakeRate; // 10**6 means for every 1 SHER token you want to buy, you will pay 1 USDC (10**7 means 1 SHER for 10 USDC) uint256 public immutable buyRate; // The `Sherlock.sol` contract that is a ERC721 ISherlock public immutable sherlockPosition; // Address receiving the USDC payments address public immutable receiver; // Contract to claim SHER at ISherClaim public immutable sherClaim; /// @notice Construct BuySher contract /// @param _sher ERC20 contract for SHER token /// @param _usdc ERC20 contract for USDC token /// @param _stakeRate Rate at which SHER tokens translate to the amount of USDC needed to be staked /// @param _buyRate Rate at which SHER tokens translate to the amount of USDC needed to be paid /// @param _sherlockPosition ERC721 contract of Sherlock positions /// @param _receiver Address that receives USDC from purchases /// @param _sherClaim Contract that keeps the SHER timelocked constructor( IERC20 _sher, IERC20 _usdc, uint256 _stakeRate, uint256 _buyRate, ISherlock _sherlockPosition, address _receiver, ISherClaim _sherClaim ) { if (address(_sher) == address(0)) revert ZeroArgument(); if (address(_usdc) == address(0)) revert ZeroArgument(); if (_stakeRate == 0) revert ZeroArgument(); if (_stakeRate % RATE_STEPS != 0) revert InvalidState(); if (_buyRate == 0) revert ZeroArgument(); if (_buyRate % RATE_STEPS != 0) revert InvalidState(); if (address(_sherlockPosition) == address(0)) revert ZeroArgument(); if (_receiver == address(0)) revert ZeroArgument(); if (address(_sherClaim) == address(0)) revert ZeroArgument(); // Verify if PERIOD is active // Theoretically this period can be disabled during the lifetime of this contract, which will cause issues if (_sherlockPosition.stakingPeriods(PERIOD) == false) revert InvalidState(); sher = _sher; usdc = _usdc; stakeRate = _stakeRate; buyRate = _buyRate; sherlockPosition = _sherlockPosition; receiver = _receiver; sherClaim = _sherClaim; // Do max approve in constructor as this contract will not hold any USDC usdc.safeIncreaseAllowance(address(sherlockPosition), type(uint256).max); } /// @notice Check if the liquidity event is active /// @dev SHER tokens can run out while event is active /// @return True if the liquidity event is active function active() public view returns (bool) { // The claim contract will become active once the liquidity event is inactive return block.timestamp < sherClaim.newEntryDeadline(); } /// @notice View the capital requirements needed to buy up until `_sherAmountWant` /// @dev Will adjust to remaining SHER if `_sherAmountWant` exceeds that /// @return sherAmount Will adjust to remining SHER if `_sherAmountWant` exceeds that /// @return stake How much USDC needs to be staked for `PERIOD` of time to buy `sherAmount` SHER /// @return price How much USDC needs to be paid to buy `sherAmount` SHER function viewCapitalRequirements(uint256 _sherAmountWant) public view returns ( uint256 sherAmount, uint256 stake, uint256 price ) { // Only allow if liquidity event is active if (active() == false) revert InvalidState(); // Zero isn't allowed if (_sherAmountWant == 0) revert ZeroArgument(); // View how much SHER is still available to be sold uint256 available = sher.balanceOf(address(this)); // If remaining SHER is 0 it's sold out if (available == 0) revert SoldOut(); // Use remaining SHER if it's less then `_sherAmountWant`, otherwise go for `_sherAmountWant` // Remaining SHER will only be assigned on the last sale of this contract, `SoldOut()` error will be thrown after // sherAmount is not able to be zero as both 'available' and '_sherAmountWant' will be bigger than 0 sherAmount = available < _sherAmountWant ? available : _sherAmountWant; // Only allows SHER amounts with certain precision steps // To ensure there is no rounding error at loss for the contract in stake / price calculation // Theoretically, if `available` is used, the function can fail if '% SHER_STEPS != 0' will be true // This can be caused by a griefer sending a small amount of SHER to the contract // Realistically, no SHER tokens will be on the market when this function is active // So it can only be caused if the admin sends too small amounts (documented at top of file with @dev) if (sherAmount % SHER_STEPS != 0) revert InvalidAmount(); // Calculate how much USDC needs to be staked to buy `sherAmount` stake = (sherAmount * stakeRate) / SHER_DECIMALS; // Calculate how much USDC needs to be paid to buy `sherAmount` price = (sherAmount * buyRate) / SHER_DECIMALS; } /// @notice Buy up until `_sherAmountWant` /// @param _sherAmountWant The maximum amount of SHER the user wants to buy /// @dev Bought SHER tokens are moved to a timelock contract (SherClaim) /// @dev Will revert if liquidity event is inactive because of the viewCapitalRequirements call function execute(uint256 _sherAmountWant) external nonReentrant { // Calculate the capital requirements // Check how much SHER can actually be bought (uint256 sherAmount, uint256 stake, uint256 price) = viewCapitalRequirements(_sherAmountWant); // Transfer usdc from user to this, for staking (max is approved in constructor) usdc.safeTransferFrom(msg.sender, address(this), stake); // Transfer usdc from user to receiver, for payment of the SHER usdc.safeTransferFrom(msg.sender, receiver, price); // Stake usdc and send NFT to user sherlockPosition.initialStake(stake, PERIOD, msg.sender); // Increase allowance for SherClaim by the amount of SHER tokens bought sher.safeIncreaseAllowance(address(sherClaim), sherAmount); // Add bought SHER tokens to timelock for user sherClaim.add(msg.sender, sherAmount); // Emit event about the purchase emit Purchase(msg.sender, sherAmount, stake, price); } /// @notice Rescue remaining ERC20 tokens when liquidity event is inactive /// @param _tokens Array of ERC20 tokens to rescue /// @dev Can only be called by `receiver` function sweepTokens(IERC20[] memory _tokens) external { if (msg.sender != receiver) revert InvalidSender(); if (active()) revert InvalidState(); // Loops through the extra tokens (ERC20) provided and sends all of them to the sender address for (uint256 i; i < _tokens.length; i++) { IERC20 token = _tokens[i]; token.safeTransfer(msg.sender, token.balanceOf(address(this))); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @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 ReentrancyGuard { // 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; constructor() { _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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ interface ISherClaim { error InvalidAmount(); error ZeroArgument(); error InvalidState(); // Event emitted when tokens have been added to the timelock event Add(address indexed sender, address indexed account, uint256 amount); // Event emitted when tokens have been claimed event Claim(address indexed account, uint256 amount); function add(address _user, uint256 _amount) external; function newEntryDeadline() external view returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '@openzeppelin/contracts/token/ERC721/IERC721.sol'; import './ISherlockStake.sol'; import './ISherlockGov.sol'; import './ISherlockPayout.sol'; import './ISherlockStrategy.sol'; interface ISherlock is ISherlockStake, ISherlockGov, ISherlockPayout, ISherlockStrategy, IERC721 { // msg.sender is not authorized to call this function error Unauthorized(); // An address or other value passed in is equal to zero (and shouldn't be) error ZeroArgument(); // Occurs when a value already holds the desired property, or is not whitelisted error InvalidArgument(); // Required conditions are not true/met error InvalidConditions(); // If the SHER tokens held in a contract are not the value they are supposed to be error InvalidSherAmount(uint256 expected, uint256 actual); // Checks the ERC-721 functions _exists() to see if an NFT ID actually exists and errors if not error NonExistent(); event ArbRestaked(uint256 indexed tokenID, uint256 reward); event Restaked(uint256 indexed tokenID); }
// 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); }
// 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); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ /// @title Sherlock core interface for stakers /// @author Evert Kors interface ISherlockStake { /// @notice View the current lockup end timestamp of `_tokenID` /// @return Timestamp when NFT position unlocks function lockupEnd(uint256 _tokenID) external view returns (uint256); /// @notice View the current SHER reward of `_tokenID` /// @return Amount of SHER rewarded to owner upon reaching the end of the lockup function sherRewards(uint256 _tokenID) external view returns (uint256); /// @notice View the current token balance claimable upon reaching end of the lockup /// @return Amount of tokens assigned to owner when unstaking position function tokenBalanceOf(uint256 _tokenID) external view returns (uint256); /// @notice View the current TVL for all stakers /// @return Total amount of tokens staked /// @dev Adds principal + strategy + premiums /// @dev Will calculate the most up to date value for each piece function totalTokenBalanceStakers() external view returns (uint256); /// @notice Stakes `_amount` of tokens and locks up for `_period` seconds, `_receiver` will receive the NFT receipt /// @param _amount Amount of tokens to stake /// @param _period Period of time, in seconds, to lockup your funds /// @param _receiver Address that will receive the NFT representing the position /// @return _id ID of the position /// @return _sher Amount of SHER tokens to be released to this ID after `_period` ends /// @dev `_period` needs to be whitelisted function initialStake( uint256 _amount, uint256 _period, address _receiver ) external returns (uint256 _id, uint256 _sher); /// @notice Redeem NFT `_id` and receive `_amount` of tokens /// @param _id TokenID of the position /// @return _amount Amount of tokens (USDC) owed to NFT ID /// @dev Only the owner of `_id` will be able to redeem their position /// @dev The SHER rewards are sent to the NFT owner /// @dev Can only be called after lockup `_period` has ended function redeemNFT(uint256 _id) external returns (uint256 _amount); /// @notice Owner restakes position with ID: `_id` for `_period` seconds /// @param _id ID of the position /// @param _period Period of time, in seconds, to lockup your funds /// @return _sher Amount of SHER tokens to be released to owner address after `_period` ends /// @dev Only the owner of `_id` will be able to restake their position using this call /// @dev `_period` needs to be whitelisted /// @dev Can only be called after lockup `_period` has ended function ownerRestake(uint256 _id, uint256 _period) external returns (uint256 _sher); /// @notice Allows someone who doesn't own the position (an arbitrager) to restake the position for 26 weeks (ARB_RESTAKE_PERIOD) /// @param _id ID of the position /// @return _sher Amount of SHER tokens to be released to position owner on expiry of the 26 weeks lockup /// @return _arbReward Amount of tokens (USDC) sent to caller (the arbitrager) in return for calling the function /// @dev Can only be called after lockup `_period` is more than 2 weeks in the past (assuming ARB_RESTAKE_WAIT_TIME is 2 weeks) /// @dev Max 20% (ARB_RESTAKE_MAX_PERCENTAGE) of tokens associated with a position are used to incentivize arbs (x) /// @dev During a 2 week period the reward ratio will move from 0% to 100% (* x) function arbRestake(uint256 _id) external returns (uint256 _sher, uint256 _arbReward); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './managers/ISherDistributionManager.sol'; import './managers/ISherlockProtocolManager.sol'; import './managers/ISherlockClaimManager.sol'; import './managers/IStrategyManager.sol'; /// @title Sherlock core interface for governance /// @author Evert Kors interface ISherlockGov { event ClaimPayout(address receiver, uint256 amount); event YieldStrategyUpdateWithdrawAllError(bytes error); event YieldStrategyUpdated(IStrategyManager previous, IStrategyManager current); event ProtocolManagerUpdated(ISherlockProtocolManager previous, ISherlockProtocolManager current); event ClaimManagerUpdated(ISherlockClaimManager previous, ISherlockClaimManager current); event NonStakerAddressUpdated(address previous, address current); event SherDistributionManagerUpdated( ISherDistributionManager previous, ISherDistributionManager current ); event StakingPeriodEnabled(uint256 period); event StakingPeriodDisabled(uint256 period); /// @notice Allows stakers to stake for `_period` of time /// @param _period Period of time, in seconds, /// @dev should revert if already enabled function enableStakingPeriod(uint256 _period) external; /// @notice Disallow stakers to stake for `_period` of time /// @param _period Period of time, in seconds, /// @dev should revert if already disabled function disableStakingPeriod(uint256 _period) external; /// @notice View if `_period` is a valid period /// @return Boolean indicating if period is valid function stakingPeriods(uint256 _period) external view returns (bool); /// @notice Update SHER distribution manager contract /// @param _sherDistributionManager New adddress of the manager function updateSherDistributionManager(ISherDistributionManager _sherDistributionManager) external; /// @notice Deletes the SHER distribution manager altogether (if Sherlock decides to no longer pay out SHER rewards) function removeSherDistributionManager() external; /// @notice Read SHER distribution manager /// @return Address of current SHER distribution manager function sherDistributionManager() external view returns (ISherDistributionManager); /// @notice Update address eligible for non staker rewards from protocol premiums /// @param _nonStakers Address eligible for non staker rewards function updateNonStakersAddress(address _nonStakers) external; /// @notice View current non stakers address /// @return Current non staker address /// @dev Is able to pull funds out of the contract function nonStakersAddress() external view returns (address); /// @notice View current address able to manage protocols /// @return Protocol manager implemenation function sherlockProtocolManager() external view returns (ISherlockProtocolManager); /// @notice Transfer protocol manager implementation address /// @param _protocolManager new implementation address function updateSherlockProtocolManager(ISherlockProtocolManager _protocolManager) external; /// @notice View current address able to pull payouts /// @return Address able to pull payouts function sherlockClaimManager() external view returns (ISherlockClaimManager); /// @notice Transfer claim manager role to different address /// @param _claimManager New address of claim manager function updateSherlockClaimManager(ISherlockClaimManager _claimManager) external; /// @notice Update yield strategy /// @param _yieldStrategy New address of the strategy /// @dev try a yieldStrategyWithdrawAll() on old, ignore failure function updateYieldStrategy(IStrategyManager _yieldStrategy) external; /// @notice Update yield strategy ignoring current state /// @param _yieldStrategy New address of the strategy /// @dev tries a yieldStrategyWithdrawAll() on old strategy, ignore failure function updateYieldStrategyForce(IStrategyManager _yieldStrategy) external; /// @notice Read current strategy /// @return Address of current strategy /// @dev can never be address(0) function yieldStrategy() external view returns (IStrategyManager); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ /// @title Sherlock interface for payout manager /// @author Evert Kors interface ISherlockPayout { /// @notice Initiate a payout of `_amount` to `_receiver` /// @param _receiver Receiver of payout /// @param _amount Amount to send /// @dev only payout manager should call this /// @dev should pull money out of strategy function payoutClaim(address _receiver, uint256 _amount) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './managers/IStrategyManager.sol'; /// @title Sherlock core interface for yield strategy /// @author Evert Kors interface ISherlockStrategy { /// @notice Deposit `_amount` into active strategy /// @param _amount Amount of tokens /// @dev gov only function yieldStrategyDeposit(uint256 _amount) external; /// @notice Withdraw `_amount` from active strategy /// @param _amount Amount of tokens /// @dev gov only function yieldStrategyWithdraw(uint256 _amount) external; /// @notice Withdraw all funds from active strategy /// @dev gov only function yieldStrategyWithdrawAll() external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import './IManager.sol'; interface ISherDistributionManager is IManager { // anyone can just send token to this contract to fund rewards event Initialized(uint256 maxRewardsEndTVL, uint256 zeroRewardsStartTVL, uint256 maxRewardRate); /// @notice Caller will receive `_sher` SHER tokens based on `_amount` and `_period` /// @param _amount Amount of tokens (in USDC) staked /// @param _period Period of time for stake, in seconds /// @param _id ID for this NFT position /// @param _receiver Address that will be linked to this position /// @return _sher Amount of SHER tokens sent to Sherlock core contract /// @dev Calling contract will depend on before + after balance diff and return value /// @dev INCLUDES stake in calculation, function expects the `_amount` to be deposited already /// @dev If tvl=50 and amount=50, this means it is calculating SHER rewards for the first 50 tokens going in function pullReward( uint256 _amount, uint256 _period, uint256 _id, address _receiver ) external returns (uint256 _sher); /// @notice Calculates how many `_sher` SHER tokens are owed to a stake position based on `_amount` and `_period` /// @param _tvl TVL to use for reward calculation (pre-stake TVL) /// @param _amount Amount of tokens (USDC) staked /// @param _period Stake period (in seconds) /// @return _sher Amount of SHER tokens owed to this stake position /// @dev EXCLUDES `_amount` of stake, this will be added on top of TVL (_tvl is excluding _amount) /// @dev If tvl=0 and amount=50, it would calculate for the first 50 tokens going in (different from pullReward()) function calcReward( uint256 _tvl, uint256 _amount, uint256 _period ) external view returns (uint256 _sher); /// @notice Function used to check if this is the current active distribution manager /// @return Boolean indicating it's active /// @dev If inactive the owner can pull all ERC20s and ETH /// @dev Will be checked by calling the sherlock contract function isActive() external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './IManager.sol'; /// @title Sherlock core interface for protocols /// @author Evert Kors interface ISherlockProtocolManager is IManager { // msg.sender is not authorized to call this function error Unauthorized(); // If a protocol was never instantiated or was removed and the claim deadline has passed, this error is returned error ProtocolNotExists(bytes32 protocol); // When comparing two arrays and the lengths are not equal (but are supposed to be equal) error UnequalArrayLength(); // If there is not enough balance in the contract for the amount requested (after any requirements are met), this is returned error InsufficientBalance(bytes32 protocol); event MinBalance(uint256 previous, uint256 current); event AccountingError(bytes32 indexed protocol, uint256 amount, uint256 insufficientTokens); event ProtocolAdded(bytes32 indexed protocol); event ProtocolRemovedByArb(bytes32 indexed protocol, address arb, uint256 profit); event ProtocolRemoved(bytes32 indexed protocol); event ProtocolUpdated( bytes32 indexed protocol, bytes32 coverage, uint256 nonStakers, uint256 coverageAmount ); event ProtocolAgentTransfer(bytes32 indexed protocol, address from, address to); event ProtocolBalanceDeposited(bytes32 indexed protocol, uint256 amount); event ProtocolBalanceWithdrawn(bytes32 indexed protocol, uint256 amount); event ProtocolPremiumChanged(bytes32 indexed protocol, uint256 oldPremium, uint256 newPremium); /// @notice View current amount of all premiums that are owed to stakers /// @return Premiums claimable /// @dev Will increase every block /// @dev base + (now - last_settled) * ps function claimablePremiums() external view returns (uint256); /// @notice Transfer current claimable premiums (for stakers) to core Sherlock address /// @dev Callable by everyone /// @dev Funds will be transferred to Sherlock core contract function claimPremiumsForStakers() external; /// @notice View current protocolAgent of `_protocol` /// @param _protocol Protocol identifier /// @return Address able to submit claims function protocolAgent(bytes32 _protocol) external view returns (address); /// @notice View current premium of protocol /// @param _protocol Protocol identifier /// @return Amount of premium `_protocol` pays per second function premium(bytes32 _protocol) external view returns (uint256); /// @notice View current active balance of covered protocol /// @param _protocol Protocol identifier /// @return Active balance /// @dev Accrued debt is subtracted from the stored active balance function activeBalance(bytes32 _protocol) external view returns (uint256); /// @notice View seconds of coverage left for `_protocol` before it runs out of active balance /// @param _protocol Protocol identifier /// @return Seconds of coverage left function secondsOfCoverageLeft(bytes32 _protocol) external view returns (uint256); /// @notice Add a new protocol to Sherlock /// @param _protocol Protocol identifier /// @param _protocolAgent Address able to submit a claim on behalf of the protocol /// @param _coverage Hash referencing the active coverage agreement /// @param _nonStakers Percentage of premium payments to nonstakers, scaled by 10**18 /// @param _coverageAmount Max amount claimable by this protocol /// @dev Adding a protocol allows the `_protocolAgent` to submit a claim /// @dev Coverage is not started yet as the protocol doesn't pay a premium at this point /// @dev `_nonStakers` is scaled by 10**18 /// @dev Only callable by governance function protocolAdd( bytes32 _protocol, address _protocolAgent, bytes32 _coverage, uint256 _nonStakers, uint256 _coverageAmount ) external; /// @notice Update info regarding a protocol /// @param _protocol Protocol identifier /// @param _coverage Hash referencing the active coverage agreement /// @param _nonStakers Percentage of premium payments to nonstakers, scaled by 10**18 /// @param _coverageAmount Max amount claimable by this protocol /// @dev Only callable by governance function protocolUpdate( bytes32 _protocol, bytes32 _coverage, uint256 _nonStakers, uint256 _coverageAmount ) external; /// @notice Remove a protocol from coverage /// @param _protocol Protocol identifier /// @dev Before removing a protocol the premium must be 0 /// @dev Removing a protocol basically stops the `_protocolAgent` from being active (can still submit claims until claim deadline though) /// @dev Pays off debt + sends remaining balance to protocol agent /// @dev This call should be subject to a timelock /// @dev Only callable by governance function protocolRemove(bytes32 _protocol) external; /// @notice Remove a protocol with insufficient active balance /// @param _protocol Protocol identifier function forceRemoveByActiveBalance(bytes32 _protocol) external; /// @notice Removes a protocol with insufficent seconds of coverage left /// @param _protocol Protocol identifier function forceRemoveBySecondsOfCoverage(bytes32 _protocol) external; /// @notice View minimal balance needed before liquidation can start /// @return Minimal balance needed function minActiveBalance() external view returns (uint256); /// @notice Sets the minimum active balance before an arb can remove a protocol /// @param _minActiveBalance Minimum balance needed (in USDC) /// @dev Only gov function setMinActiveBalance(uint256 _minActiveBalance) external; /// @notice Set premium of `_protocol` to `_premium` /// @param _protocol Protocol identifier /// @param _premium Amount of premium `_protocol` pays per second /// @dev The value 0 would mean inactive coverage /// @dev Only callable by governance function setProtocolPremium(bytes32 _protocol, uint256 _premium) external; /// @notice Set premium of multiple protocols /// @param _protocol Array of protocol identifiers /// @param _premium Array of premium amounts protocols pay per second /// @dev The value 0 would mean inactive coverage /// @dev Only callable by governance function setProtocolPremiums(bytes32[] calldata _protocol, uint256[] calldata _premium) external; /// @notice Deposits `_amount` of token to the active balance of `_protocol` /// @param _protocol Protocol identifier /// @param _amount Amount of tokens to deposit /// @dev Approval should be made before calling function depositToActiveBalance(bytes32 _protocol, uint256 _amount) external; /// @notice Withdraws `_amount` of token from the active balance of `_protocol` /// @param _protocol Protocol identifier /// @param _amount Amount of tokens to withdraw /// @dev Only protocol agent is able to withdraw /// @dev Balance can be withdrawn up until 7 days worth of active balance function withdrawActiveBalance(bytes32 _protocol, uint256 _amount) external; /// @notice Transfer protocol agent role /// @param _protocol Protocol identifier /// @param _protocolAgent Account able to submit a claim on behalf of the protocol /// @dev Only the active protocolAgent is able to transfer the role function transferProtocolAgent(bytes32 _protocol, address _protocolAgent) external; /// @notice View the amount nonstakers can claim from this protocol /// @param _protocol Protocol identifier /// @return Amount of tokens claimable by nonstakers /// @dev this reads from a storage variable + (now-lastsettled) * premiums function nonStakersClaimable(bytes32 _protocol) external view returns (uint256); /// @notice Choose an `_amount` of tokens that nonstakers (`_receiver` address) will receive from `_protocol` /// @param _protocol Protocol identifier /// @param _amount Amount of tokens /// @param _receiver Address to receive tokens /// @dev Only callable by nonstakers role function nonStakersClaim( bytes32 _protocol, uint256 _amount, address _receiver ) external; /// @param _protocol Protocol identifier /// @return current and previous are the current and previous coverage amounts for this protocol function coverageAmounts(bytes32 _protocol) external view returns (uint256 current, uint256 previous); /// @notice Function used to check if this is the current active protocol manager /// @return Boolean indicating it's active /// @dev If inactive the owner can pull all ERC20s and ETH /// @dev Will be checked by calling the sherlock contract function isActive() external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import './callbacks/ISherlockClaimManagerCallbackReceiver.sol'; import '../UMAprotocol/OptimisticRequester.sol'; import './IManager.sol'; interface ISherlockClaimManager is IManager, OptimisticRequester { // Doesn't allow a new claim to be submitted by a protocol agent if a claim is already active for that protocol error ClaimActive(); // If the current state of a claim does not match the expected state, this error is thrown error InvalidState(); event ClaimCreated( uint256 claimID, bytes32 indexed protocol, uint256 amount, address receiver, bool previousCoverageUsed ); event CallbackAdded(ISherlockClaimManagerCallbackReceiver callback); event CallbackRemoved(ISherlockClaimManagerCallbackReceiver callback); event ClaimStatusChanged(uint256 indexed claimID, State previousState, State currentState); event ClaimPayout(uint256 claimID, address receiver, uint256 amount); event ClaimHalted(uint256 claimID); event UMAHORenounced(); enum State { NonExistent, // Claim doesn't exist (this is the default state on creation) SpccPending, // Claim is created, SPCC is able to set state to valid SpccApproved, // Final state, claim is valid SpccDenied, // Claim denied by SPCC, claim can be escalated within 4 weeks UmaPriceProposed, // Price is proposed but not escalated ReadyToProposeUmaDispute, // Price is proposed, callback received, ready to submit dispute UmaDisputeProposed, // Escalation is done, waiting for confirmation UmaPending, // Claim is escalated, in case Spcc denied or didn't act within 7 days. UmaApproved, // Final state, claim is valid, claim can be enacted after 1 day, umaHaltOperator has 1 day to change to denied UmaDenied, // Final state, claim is invalid Halted, // UMAHO can halt claim if state is UmaApproved Cleaned // Claim is removed by protocol agent } struct Claim { uint256 created; uint256 updated; address initiator; bytes32 protocol; uint256 amount; address receiver; uint32 timestamp; State state; bytes ancillaryData; } // requestAndProposePriceFor() --> proposer = sherlockCore (address to receive BOND if UMA denies claim) // disputePriceFor() --> disputer = protocolAgent // priceSettled will be the the callback that contains the main data // Assume BOND = 9600, UMA's final fee = 1500. // Claim initiator (Sherlock) has to pay 22.2k to dispute a claim, // so we will execute a safeTransferFrom(claimInitiator, address(this), 22.2k). // We need to approve the contract 22.2k as it will be transferred from address(this). // The 22.2k consists of 2 * (BOND + final fee charged by UMA), as follows: // 1. On requestAndProposePriceFor(), the fee will be 10k: 9600 BOND + 1500 UMA's final fee; // 2. On disputePriceFor(), the fee will be the same 10k. // note that half of the BOND (4800) + UMA's final fee (1500) is "burnt" and sent to UMA // UMA's final fee can be changed in the future, which may result in lower or higher required staked amounts for escalating a claim. // On settle, either the protocolAgent (dispute success) or sherlockCore (dispute failure) // will receive 9600 + 4800 + 1500 = 15900. In addition, the protocolAgent will be entitled to // the claimAmount if the dispute is successful/ // lastClaimID <-- starts with 0, so initial id = 1 // have claim counter, easy to identify certain claims by their number // but use hash(callback.request.propose + callback.timestamp) as the internal UUID to handle the callbacks // So SPCC and UMAHO are hardcoded (UMAHO can be renounced) // In case these need to be updated, deploy different contract and upgrade it on the sherlock gov side. // On price proposed callback --> call disputePriceFor with callbackdata + sherlock.strategyManager() and address(this) /// @notice `SHERLOCK_CLAIM` in utf8 function UMA_IDENTIFIER() external view returns (bytes32); function sherlockProtocolClaimsCommittee() external view returns (address); /// @notice operator is able to deny approved UMA claims function umaHaltOperator() external view returns (address); /// @notice gov is able to renounce the role function renounceUmaHaltOperator() external; function claim(uint256 _claimID) external view returns (Claim memory); /// @notice Initiate a claim for a specific protocol as the protocol agent /// @param _protocol protocol ID (different from the internal or public claim ID fields) /// @param _amount amount of USDC which is being claimed by the protocol /// @param _receiver address to receive the amount of USDC being claimed /// @param _timestamp timestamp at which the exploit first occurred /// @param ancillaryData other data associated with the claim, such as the coverage agreement /// @dev The protocol agent that starts a claim will be the protocol agent during the claims lifecycle /// @dev Even if the protocol agent role is tranferred during the lifecycle function startClaim( bytes32 _protocol, uint256 _amount, address _receiver, uint32 _timestamp, bytes memory ancillaryData ) external; function spccApprove(uint256 _claimID) external; function spccRefuse(uint256 _claimID) external; /// @notice Callable by protocol agent /// @param _claimID Public claim ID /// @param _amount Bond amount sent by protocol agent /// @dev Use hardcoded USDC address /// @dev Use hardcoded bond amount /// @dev Use hardcoded liveness 7200 (2 hours) /// @dev proposedPrice = _amount function escalate(uint256 _claimID, uint256 _amount) external; /// @notice Execute claim, storage will be removed after /// @param _claimID Public ID of the claim /// @dev Needs to be SpccApproved or UmaApproved && >UMAHO_TIME /// @dev Funds will be pulled from core function payoutClaim(uint256 _claimID) external; /// @notice UMAHO is able to execute a halt if the state is UmaApproved and state was updated less than UMAHO_TIME ago function executeHalt(uint256 _claimID) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import './IManager.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IStrategyManager is IManager { /// @return Returns the token type being deposited into a strategy function want() external view returns (IERC20); /// @notice Withdraws all USDC from the strategy back into the Sherlock core contract /// @dev Only callable by the Sherlock core contract /// @return The final amount withdrawn function withdrawAll() external returns (uint256); /// @notice Withdraws a specific amount of USDC from the strategy back into the Sherlock core contract /// @param _amount Amount of USDC to withdraw function withdraw(uint256 _amount) external; /// @notice Deposits all USDC held in this contract into the strategy function deposit() external; /// @return Returns the USDC balance in this contract function balanceOf() external view returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ import '../ISherlock.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IManager { // An address or other value passed in is equal to zero (and shouldn't be) error ZeroArgument(); // Occurs when a value already holds the desired property, or is not whitelisted error InvalidArgument(); // If a required condition for executing the function is not met, it reverts and throws this error error InvalidConditions(); // Throws if the msg.sender is not the required address error InvalidSender(); event SherlockCoreSet(ISherlock sherlock); /// @notice Set sherlock core address where premiums should be send too /// @param _sherlock Current core contract /// @dev Only deployer is able to set core address on all chains except Hardhat network /// @dev One time function, will revert once `sherlock` != address(0) /// @dev This contract will be deployed first, passed on as argument in core constuctor /// @dev ^ that's needed for tvl accounting, once core is deployed this function is called /// @dev emits `SherlockCoreSet` function setSherlockCoreAddress(ISherlock _sherlock) external; /// @notice Pause external functions in contract function pause() external; /// @notice Unpause external functions in contract function unpause() external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /******************************************************************************\ * Author: Evert Kors <[email protected]> (https://twitter.com/evert0x) * Sherlock Protocol: https://sherlock.xyz /******************************************************************************/ interface ISherlockClaimManagerCallbackReceiver { /// @notice Calls this function on approved contracts and passes args /// @param _protocol The protocol that is receiving the payout /// @param _claimID The claim ID that is receiving the payout /// @param _amount The amount of USDC being paid out for this claim function PreCorePayoutCallback( bytes32 _protocol, uint256 _claimID, uint256 _amount ) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; import './SkinnyOptimisticOracleInterface.sol'; /** * @title Optimistic Requester. * @notice Optional interface that requesters can implement to receive callbacks. * @dev This contract does _not_ work with ERC777 collateral currencies or any others that call into the receiver on * transfer(). Using an ERC777 token would allow a user to maliciously grief other participants (while also losing * money themselves). */ interface OptimisticRequester { /** * @notice Callback for proposals. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data of the price being requested. * @param request request params after proposal. */ function priceProposed( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, SkinnyOptimisticOracleInterface.Request memory request ) external; /** * @notice Callback for disputes. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data of the price being requested. * @param request request params after dispute. */ function priceDisputed( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, SkinnyOptimisticOracleInterface.Request memory request ) external; /** * @notice Callback for settlement. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data of the price being requested. * @param request request params after settlement. */ function priceSettled( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, SkinnyOptimisticOracleInterface.Request memory request ) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import './OptimisticOracleInterface.sol'; /** * @title Interface for the gas-cost-reduced version of the OptimisticOracle. * @notice Differences from normal OptimisticOracle: * - refundOnDispute: flag is removed, by default there are no refunds on disputes. * - customizing request parameters: In the OptimisticOracle, parameters like `bond` and `customLiveness` can be reset * after a request is already made via `requestPrice`. In the SkinnyOptimisticOracle, these parameters can only be * set in `requestPrice`, which has an expanded input set. * - settleAndGetPrice: Replaced by `settle`, which can only be called once per settleable request. The resolved price * can be fetched via the `Settle` event or the return value of `settle`. * - general changes to interface: Functions that interact with existing requests all require the parameters of the * request to modify to be passed as input. These parameters must match with the existing request parameters or the * function will revert. This change reflects the internal refactor to store hashed request parameters instead of the * full request struct. * @dev Interface used by financial contracts to interact with the Oracle. Voters will use a different interface. */ abstract contract SkinnyOptimisticOracleInterface { event RequestPrice( address indexed requester, bytes32 indexed identifier, uint32 timestamp, bytes ancillaryData, Request request ); event ProposePrice( address indexed requester, bytes32 indexed identifier, uint32 timestamp, bytes ancillaryData, Request request ); event DisputePrice( address indexed requester, bytes32 indexed identifier, uint32 timestamp, bytes ancillaryData, Request request ); event Settle( address indexed requester, bytes32 indexed identifier, uint32 timestamp, bytes ancillaryData, Request request ); // Struct representing a price request. Note that this differs from the OptimisticOracleInterface's Request struct // in that refundOnDispute is removed. struct Request { address proposer; // Address of the proposer. address disputer; // Address of the disputer. IERC20 currency; // ERC20 token used to pay rewards and fees. bool settled; // True if the request is settled. int256 proposedPrice; // Price that the proposer submitted. int256 resolvedPrice; // Price resolved once the request is settled. uint256 expirationTime; // Time at which the request auto-settles without a dispute. uint256 reward; // Amount of the currency to pay to the proposer on settlement. uint256 finalFee; // Final fee to pay to the Store upon request to the DVM. uint256 bond; // Bond that the proposer and disputer must pay on top of the final fee. uint256 customLiveness; // Custom liveness value set by the requester. } // This value must be <= the Voting contract's `ancillaryBytesLimit` value otherwise it is possible // that a price can be requested to this contract successfully, but cannot be disputed because the DVM refuses // to accept a price request made with ancillary data length over a certain size. uint256 public constant ancillaryBytesLimit = 8192; /** * @notice Requests a new price. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data representing additional args being passed with the price request. * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, * which could make sense if the contract requests and proposes the value in the same call or * provides its own reward system. * @param bond custom proposal bond to set for request. If set to 0, defaults to the final fee. * @param customLiveness custom proposal liveness to set for request. * @return totalBond default bond + final fee that the proposer and disputer will be required to pay. */ function requestPrice( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, IERC20 currency, uint256 reward, uint256 bond, uint256 customLiveness ) external virtual returns (uint256 totalBond); /** * @notice Proposes a price value on another address' behalf. Note: this address will receive any rewards that come * from this proposal. However, any bonds are pulled from the caller. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * propose a price for. * @param proposer address to set as the proposer. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function proposePriceFor( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request, address proposer, int256 proposedPrice ) public virtual returns (uint256 totalBond); /** * @notice Proposes a price value where caller is the proposer. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * propose a price for. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function proposePrice( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request, int256 proposedPrice ) external virtual returns (uint256 totalBond); /** * @notice Combines logic of requestPrice and proposePrice while taking advantage of gas savings from not having to * overwrite Request params that a normal requestPrice() => proposePrice() flow would entail. Note: The proposer * will receive any rewards that come from this proposal. However, any bonds are pulled from the caller. * @dev The caller is the requester, but the proposer can be customized. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, * which could make sense if the contract requests and proposes the value in the same call or * provides its own reward system. * @param bond custom proposal bond to set for request. If set to 0, defaults to the final fee. * @param customLiveness custom proposal liveness to set for request. * @param proposer address to set as the proposer. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function requestAndProposePriceFor( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, IERC20 currency, uint256 reward, uint256 bond, uint256 customLiveness, address proposer, int256 proposedPrice ) external virtual returns (uint256 totalBond); /** * @notice Disputes a price request with an active proposal on another address' behalf. Note: this address will * receive any rewards that come from this dispute. However, any bonds are pulled from the caller. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * dispute. * @param disputer address to set as the disputer. * @param requester sender of the initial price request. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the disputer once settled if the dispute was valid (the proposal was incorrect). */ function disputePriceFor( bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request, address disputer, address requester ) public virtual returns (uint256 totalBond); /** * @notice Disputes a price request with an active proposal where caller is the disputer. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * dispute. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the disputer once settled if the dispute was valid (the proposal was incorrect). */ function disputePrice( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request ) external virtual returns (uint256 totalBond); /** * @notice Attempts to settle an outstanding price request. Will revert if it isn't settleable. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters whose hash must match the request that the caller wants to * settle. * @return payout the amount that the "winner" (proposer or disputer) receives on settlement. This amount includes * the returned bonds as well as additional rewards. * @return resolvedPrice the price that the request settled to. */ function settle( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request ) external virtual returns (uint256 payout, int256 resolvedPrice); /** * @notice Computes the current state of a price request. See the State enum for more details. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters. * @return the State. */ function getState( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request ) external virtual returns (OptimisticOracleInterface.State); /** * @notice Checks if a given request has resolved, expired or been settled (i.e the optimistic oracle has a price). * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param request price request parameters. The hash of these parameters must match with the request hash that is * associated with the price request unique ID {requester, identifier, timestamp, ancillaryData}, or this method * will revert. * @return boolean indicating true if price exists and false if not. */ function hasPrice( address requester, bytes32 identifier, uint32 timestamp, bytes memory ancillaryData, Request memory request ) public virtual returns (bool); /** * @notice Generates stamped ancillary data in the format that it would be used in the case of a price dispute. * @param ancillaryData ancillary data of the price being requested. * @param requester sender of the initial price request. * @return the stamped ancillary bytes. */ function stampAncillaryData(bytes memory ancillaryData, address requester) public pure virtual returns (bytes memory); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; /** * @title Financial contract facing Oracle interface. * @dev Interface used by financial contracts to interact with the Oracle. Voters will use a different interface. */ abstract contract OptimisticOracleInterface { // Struct representing the state of a price request. enum State { Invalid, // Never requested. Requested, // Requested, no other actions taken. Proposed, // Proposed, but not expired or disputed yet. Expired, // Proposed, not disputed, past liveness. Disputed, // Disputed, but no DVM price returned yet. Resolved, // Disputed and DVM price is available. Settled // Final price has been set in the contract (can get here from Expired or Resolved). } // Struct representing a price request. struct Request { address proposer; // Address of the proposer. address disputer; // Address of the disputer. IERC20 currency; // ERC20 token used to pay rewards and fees. bool settled; // True if the request is settled. bool refundOnDispute; // True if the requester should be refunded their reward on dispute. int256 proposedPrice; // Price that the proposer submitted. int256 resolvedPrice; // Price resolved once the request is settled. uint256 expirationTime; // Time at which the request auto-settles without a dispute. uint256 reward; // Amount of the currency to pay to the proposer on settlement. uint256 finalFee; // Final fee to pay to the Store upon request to the DVM. uint256 bond; // Bond that the proposer and disputer must pay on top of the final fee. uint256 customLiveness; // Custom liveness value set by the requester. } // This value must be <= the Voting contract's `ancillaryBytesLimit` value otherwise it is possible // that a price can be requested to this contract successfully, but cannot be disputed because the DVM refuses // to accept a price request made with ancillary data length over a certain size. uint256 public constant ancillaryBytesLimit = 8192; /** * @notice Requests a new price. * @param identifier price identifier being requested. * @param timestamp timestamp of the price being requested. * @param ancillaryData ancillary data representing additional args being passed with the price request. * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, * which could make sense if the contract requests and proposes the value in the same call or * provides its own reward system. * @return totalBond default bond (final fee) + final fee that the proposer and disputer will be required to pay. * This can be changed with a subsequent call to setBond(). */ function requestPrice( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, IERC20 currency, uint256 reward ) external virtual returns (uint256 totalBond); /** * @notice Set the proposal bond associated with a price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param bond custom bond amount to set. * @return totalBond new bond + final fee that the proposer and disputer will be required to pay. This can be * changed again with a subsequent call to setBond(). */ function setBond( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, uint256 bond ) external virtual returns (uint256 totalBond); /** * @notice Sets the request to refund the reward if the proposal is disputed. This can help to "hedge" the caller * in the event of a dispute-caused delay. Note: in the event of a dispute, the winner still receives the other's * bond, so there is still profit to be made even if the reward is refunded. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. */ function setRefundOnDispute( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) external virtual; /** * @notice Sets a custom liveness value for the request. Liveness is the amount of time a proposal must wait before * being auto-resolved. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param customLiveness new custom liveness. */ function setCustomLiveness( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, uint256 customLiveness ) external virtual; /** * @notice Proposes a price value on another address' behalf. Note: this address will receive any rewards that come * from this proposal. However, any bonds are pulled from the caller. * @param proposer address to set as the proposer. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function proposePriceFor( address proposer, address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, int256 proposedPrice ) public virtual returns (uint256 totalBond); /** * @notice Proposes a price value for an existing price request. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @param proposedPrice price being proposed. * @return totalBond the amount that's pulled from the proposer's wallet as a bond. The bond will be returned to * the proposer once settled if the proposal is correct. */ function proposePrice( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, int256 proposedPrice ) external virtual returns (uint256 totalBond); /** * @notice Disputes a price request with an active proposal on another address' behalf. Note: this address will * receive any rewards that come from this dispute. However, any bonds are pulled from the caller. * @param disputer address to set as the disputer. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to * the disputer once settled if the dispute was value (the proposal was incorrect). */ function disputePriceFor( address disputer, address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) public virtual returns (uint256 totalBond); /** * @notice Disputes a price value for an existing price request with an active proposal. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return totalBond the amount that's pulled from the disputer's wallet as a bond. The bond will be returned to * the disputer once settled if the dispute was valid (the proposal was incorrect). */ function disputePrice( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) external virtual returns (uint256 totalBond); /** * @notice Retrieves a price that was previously requested by a caller. Reverts if the request is not settled * or settleable. Note: this method is not view so that this call may actually settle the price request if it * hasn't been settled. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return resolved price. */ function settleAndGetPrice( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) external virtual returns (int256); /** * @notice Attempts to settle an outstanding price request. Will revert if it isn't settleable. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return payout the amount that the "winner" (proposer or disputer) receives on settlement. This amount includes * the returned bonds as well as additional rewards. */ function settle( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) external virtual returns (uint256 payout); /** * @notice Gets the current data structure containing all information about a price request. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return the Request data structure. */ function getRequest( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) public view virtual returns (Request memory); /** * @notice Returns the state of a price request. * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return the State enum value. */ function getState( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) public view virtual returns (State); /** * @notice Checks if a given request has resolved or been settled (i.e the optimistic oracle has a price). * @param requester sender of the initial price request. * @param identifier price identifier to identify the existing request. * @param timestamp timestamp to identify the existing request. * @param ancillaryData ancillary data of the price being requested. * @return true if price has resolved or settled, false otherwise. */ function hasPrice( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) public view virtual returns (bool); function stampAncillaryData(bytes memory ancillaryData, address requester) public view virtual returns (bytes memory); }
{ "optimizer": { "enabled": true, "runs": 20000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"_sher","type":"address"},{"internalType":"contract IERC20","name":"_usdc","type":"address"},{"internalType":"uint256","name":"_stakeRate","type":"uint256"},{"internalType":"uint256","name":"_buyRate","type":"uint256"},{"internalType":"contract ISherlock","name":"_sherlockPosition","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"contract ISherClaim","name":"_sherClaim","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidState","type":"error"},{"inputs":[],"name":"SoldOut","type":"error"},{"inputs":[],"name":"ZeroArgument","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"staked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paid","type":"uint256"}],"name":"Purchase","type":"event"},{"inputs":[],"name":"PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"active","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sherAmountWant","type":"uint256"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"receiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sher","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sherClaim","outputs":[{"internalType":"contract ISherClaim","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sherlockPosition","outputs":[{"internalType":"contract ISherlock","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20[]","name":"_tokens","type":"address[]"}],"name":"sweepTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sherAmountWant","type":"uint256"}],"name":"viewCapitalRequirements","outputs":[{"internalType":"uint256","name":"sherAmount","type":"uint256"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101606040523480156200001257600080fd5b5060405162001b9938038062001b998339810160408190526200003591620005f6565b60016000556001600160a01b038716620000625760405163b7852ebb60e01b815260040160405180910390fd5b6001600160a01b0386166200008a5760405163b7852ebb60e01b815260040160405180910390fd5b84620000a95760405163b7852ebb60e01b815260040160405180910390fd5b620000b7612710866200068a565b15620000d65760405163baf3f0f760e01b815260040160405180910390fd5b83620000f55760405163b7852ebb60e01b815260040160405180910390fd5b62000103612710856200068a565b15620001225760405163baf3f0f760e01b815260040160405180910390fd5b6001600160a01b0383166200014a5760405163b7852ebb60e01b815260040160405180910390fd5b6001600160a01b038216620001725760405163b7852ebb60e01b815260040160405180910390fd5b6001600160a01b0381166200019a5760405163b7852ebb60e01b815260040160405180910390fd5b604051638af92c9360e01b815262eff10060048201526001600160a01b03841690638af92c9390602401602060405180830381865afa158015620001e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002089190620006ad565b620002265760405163baf3f0f760e01b815260040160405180910390fd5b6001600160a01b0387811660805286811660a081905260c087905260e08690528482166101008190528483166101205291831661014052620002779160001962000284602090811b62000a5f17901c565b5050505050505062000794565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620002d6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fc9190620006d1565b620003089190620006eb565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000364918691906200036a16565b50505050565b6000620003c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200045160201b62000be1179092919060201c565b8051909150156200044c5780806020019051810190620003e79190620006ad565b6200044c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b505050565b60606200046284846000856200046c565b90505b9392505050565b606082471015620004cf5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000443565b843b6200051f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000443565b600080866001600160a01b031685876040516200053d919062000741565b60006040518083038185875af1925050503d80600081146200057c576040519150601f19603f3d011682016040523d82523d6000602084013e62000581565b606091505b509092509050620005948282866200059f565b979650505050505050565b60608315620005b057508162000465565b825115620005c15782518084602001fd5b8160405162461bcd60e51b81526004016200044391906200075f565b6001600160a01b0381168114620005f357600080fd5b50565b600080600080600080600060e0888a0312156200061257600080fd5b87516200061f81620005dd565b60208901519097506200063281620005dd565b80965050604088015194506060880151935060808801516200065481620005dd565b60a08901519093506200066781620005dd565b60c08901519092506200067a81620005dd565b8091505092959891949750929550565b600082620006a857634e487b7160e01b600052601260045260246000fd5b500690565b600060208284031215620006c057600080fd5b815180151581146200046557600080fd5b600060208284031215620006e457600080fd5b5051919050565b600082198211156200070d57634e487b7160e01b600052601160045260246000fd5b500190565b60005b838110156200072f57818101518382015260200162000715565b83811115620003645750506000910152565b600082516200075581846020870162000712565b9190910192915050565b60208152600082518060208401526200078081604085016020870162000712565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161135762000842600039600081816101f00152818161029e0152818161094601526109a00152600081816102170152818161058c0152610823015260008181610278015261088601526000818161023e015261053c01526000818161017501526104fd01526000818160fb015281816107be01526108000152600081816101bf015281816103dd015261092401526113576000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063b4d1d79511610081578063fc37987b1161005b578063fc37987b14610239578063fe0d94c114610260578063fee479d31461027357600080fd5b8063b4d1d795146101e1578063d933b3c0146101eb578063f7260d3e1461021257600080fd5b806381160fe3116100b257806381160fe314610170578063909b19d9146101a5578063937840b0146101ba57600080fd5b806302fb0c5e146100d95780633e413bee146100f657806342a14b8114610142575b600080fd5b6100e161029a565b60405190151581526020015b60405180910390f35b61011d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b610155610150366004610f92565b610332565b604080519384526020840192909252908201526060016100ed565b6101977f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100ed565b6101b86101b3366004611003565b610574565b005b61011d7f000000000000000000000000000000000000000000000000000000000000000081565b61019762eff10081565b61011d7f000000000000000000000000000000000000000000000000000000000000000081565b61011d7f000000000000000000000000000000000000000000000000000000000000000081565b6101977f000000000000000000000000000000000000000000000000000000000000000081565b6101b861026e366004610f92565b610719565b61011d7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e59e175b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061032b91906110e6565b4210905090565b600080600061033f61029a565b610375576040517fbaf3f0f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836103ac576040517fb7852ebb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061045d91906110e6565b905080610496576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8481106104a357846104a5565b805b93506104b8662386f26fc100008561112e565b156104ef576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b670de0b6b3a76400006105227f000000000000000000000000000000000000000000000000000000000000000086611171565b61052c91906111ae565b9250670de0b6b3a76400006105617f000000000000000000000000000000000000000000000000000000000000000086611171565b61056b91906111ae565b93959294505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105e3576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105eb61029a565b15610622576040517fbaf3f0f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8151811015610715576000828281518110610642576106426111c2565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915061070290339073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156106c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e491906110e6565b73ffffffffffffffffffffffffffffffffffffffff84169190610bfa565b508061070d816111f1565b915050610625565b5050565b6002600054141561078b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000908155808061079d84610332565b919450925090506107e673ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333085610c55565b61084873ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016337f000000000000000000000000000000000000000000000000000000000000000084610c55565b6040517f2f5cf62b0000000000000000000000000000000000000000000000000000000081526004810183905262eff10060248201523360448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632f5cf62b9060640160408051808303816000875af11580156108e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610907919061122a565b5061096b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000085610a5f565b6040517ff5d82b6b000000000000000000000000000000000000000000000000000000008152336004820152602481018490527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063f5d82b6b90604401600060405180830381600087803b1580156109f957600080fd5b505af1158015610a0d573d6000803e3d6000fd5b505060408051868152602081018690529081018490523392507f5bc97d73357ac0d035d4b9268a69240988a5776b8a4fcced3dbc223960123f40915060600160405180910390a2505060016000555050565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015610ad6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afa91906110e6565b610b04919061124e565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260448101829052909150610bdb9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610cb3565b50505050565b6060610bf08484600085610dbf565b90505b9392505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c509084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610b59565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610bdb9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610b59565b6000610d15826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610be19092919063ffffffff16565b805190915015610c505780806020019051810190610d339190611266565b610c50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610782565b606082471015610e51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610782565b843b610eb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610782565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610ee291906112b4565b60006040518083038185875af1925050503d8060008114610f1f576040519150601f19603f3d011682016040523d82523d6000602084013e610f24565b606091505b5091509150610f34828286610f3f565b979650505050505050565b60608315610f4e575081610bf3565b825115610f5e5782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078291906112d0565b600060208284031215610fa457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610ffe57600080fd5b919050565b6000602080838503121561101657600080fd5b823567ffffffffffffffff8082111561102e57600080fd5b818501915085601f83011261104257600080fd5b81358181111561105457611054610fab565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561109757611097610fab565b6040529182528482019250838101850191888311156110b557600080fd5b938501935b828510156110da576110cb85610fda565b845293850193928501926110ba565b98975050505050505050565b6000602082840312156110f857600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261113d5761113d6110ff565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156111a9576111a9611142565b500290565b6000826111bd576111bd6110ff565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561122357611223611142565b5060010190565b6000806040838503121561123d57600080fd5b505080516020909101519092909150565b6000821982111561126157611261611142565b500190565b60006020828403121561127857600080fd5b81518015158114610bf357600080fd5b60005b838110156112a357818101518382015260200161128b565b83811115610bdb5750506000910152565b600082516112c6818460208701611288565b9190910192915050565b60208152600082518060208401526112ef816040850160208701611288565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220ccfddcdde13642102a9f01eb754d34f1b4b6d8ba13d373780b6df54784698aec64736f6c634300080a003300000000000000000000000046d2a90153cd8f09464ca3a5605b6bbec9c2ff01000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000089544000000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000865a889183039689034da55c1fd12af5083eabf000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f131610000000000000000000000007289c61c75dcdb8fe4df0b937c08c9c40902bdd3
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100d45760003560e01c8063b4d1d79511610081578063fc37987b1161005b578063fc37987b14610239578063fe0d94c114610260578063fee479d31461027357600080fd5b8063b4d1d795146101e1578063d933b3c0146101eb578063f7260d3e1461021257600080fd5b806381160fe3116100b257806381160fe314610170578063909b19d9146101a5578063937840b0146101ba57600080fd5b806302fb0c5e146100d95780633e413bee146100f657806342a14b8114610142575b600080fd5b6100e161029a565b60405190151581526020015b60405180910390f35b61011d7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b610155610150366004610f92565b610332565b604080519384526020840192909252908201526060016100ed565b6101977f000000000000000000000000000000000000000000000000000000000089544081565b6040519081526020016100ed565b6101b86101b3366004611003565b610574565b005b61011d7f00000000000000000000000046d2a90153cd8f09464ca3a5605b6bbec9c2ff0181565b61019762eff10081565b61011d7f0000000000000000000000007289c61c75dcdb8fe4df0b937c08c9c40902bdd381565b61011d7f000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f1316181565b6101977f00000000000000000000000000000000000000000000000000000000000f424081565b6101b861026e366004610f92565b610719565b61011d7f0000000000000000000000000865a889183039689034da55c1fd12af5083eabf81565b60007f0000000000000000000000007289c61c75dcdb8fe4df0b937c08c9c40902bdd373ffffffffffffffffffffffffffffffffffffffff1663e59e175b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061032b91906110e6565b4210905090565b600080600061033f61029a565b610375576040517fbaf3f0f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836103ac576040517fb7852ebb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000046d2a90153cd8f09464ca3a5605b6bbec9c2ff0173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061045d91906110e6565b905080610496576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8481106104a357846104a5565b805b93506104b8662386f26fc100008561112e565b156104ef576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b670de0b6b3a76400006105227f000000000000000000000000000000000000000000000000000000000089544086611171565b61052c91906111ae565b9250670de0b6b3a76400006105617f00000000000000000000000000000000000000000000000000000000000f424086611171565b61056b91906111ae565b93959294505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f1316116146105e3576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105eb61029a565b15610622576040517fbaf3f0f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8151811015610715576000828281518110610642576106426111c2565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915061070290339073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156106c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e491906110e6565b73ffffffffffffffffffffffffffffffffffffffff84169190610bfa565b508061070d816111f1565b915050610625565b5050565b6002600054141561078b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000908155808061079d84610332565b919450925090506107e673ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816333085610c55565b61084873ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816337f000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f1316184610c55565b6040517f2f5cf62b0000000000000000000000000000000000000000000000000000000081526004810183905262eff10060248201523360448201527f0000000000000000000000000865a889183039689034da55c1fd12af5083eabf73ffffffffffffffffffffffffffffffffffffffff1690632f5cf62b9060640160408051808303816000875af11580156108e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610907919061122a565b5061096b905073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000046d2a90153cd8f09464ca3a5605b6bbec9c2ff01167f0000000000000000000000007289c61c75dcdb8fe4df0b937c08c9c40902bdd385610a5f565b6040517ff5d82b6b000000000000000000000000000000000000000000000000000000008152336004820152602481018490527f0000000000000000000000007289c61c75dcdb8fe4df0b937c08c9c40902bdd373ffffffffffffffffffffffffffffffffffffffff169063f5d82b6b90604401600060405180830381600087803b1580156109f957600080fd5b505af1158015610a0d573d6000803e3d6000fd5b505060408051868152602081018690529081018490523392507f5bc97d73357ac0d035d4b9268a69240988a5776b8a4fcced3dbc223960123f40915060600160405180910390a2505060016000555050565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015610ad6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afa91906110e6565b610b04919061124e565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260448101829052909150610bdb9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610cb3565b50505050565b6060610bf08484600085610dbf565b90505b9392505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c509084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610b59565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610bdb9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610b59565b6000610d15826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610be19092919063ffffffff16565b805190915015610c505780806020019051810190610d339190611266565b610c50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610782565b606082471015610e51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610782565b843b610eb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610782565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610ee291906112b4565b60006040518083038185875af1925050503d8060008114610f1f576040519150601f19603f3d011682016040523d82523d6000602084013e610f24565b606091505b5091509150610f34828286610f3f565b979650505050505050565b60608315610f4e575081610bf3565b825115610f5e5782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078291906112d0565b600060208284031215610fa457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610ffe57600080fd5b919050565b6000602080838503121561101657600080fd5b823567ffffffffffffffff8082111561102e57600080fd5b818501915085601f83011261104257600080fd5b81358181111561105457611054610fab565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561109757611097610fab565b6040529182528482019250838101850191888311156110b557600080fd5b938501935b828510156110da576110cb85610fda565b845293850193928501926110ba565b98975050505050505050565b6000602082840312156110f857600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261113d5761113d6110ff565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156111a9576111a9611142565b500290565b6000826111bd576111bd6110ff565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561122357611223611142565b5060010190565b6000806040838503121561123d57600080fd5b505080516020909101519092909150565b6000821982111561126157611261611142565b500190565b60006020828403121561127857600080fd5b81518015158114610bf357600080fd5b60005b838110156112a357818101518382015260200161128b565b83811115610bdb5750506000910152565b600082516112c6818460208701611288565b9190910192915050565b60208152600082518060208401526112ef816040850160208701611288565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220ccfddcdde13642102a9f01eb754d34f1b4b6d8ba13d373780b6df54784698aec64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000046d2a90153cd8f09464ca3a5605b6bbec9c2ff01000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000089544000000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000865a889183039689034da55c1fd12af5083eabf000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f131610000000000000000000000007289c61c75dcdb8fe4df0b937c08c9c40902bdd3
-----Decoded View---------------
Arg [0] : _sher (address): 0x46D2A90153cd8F09464CA3a5605B6BBeC9C2fF01
Arg [1] : _usdc (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [2] : _stakeRate (uint256): 9000000
Arg [3] : _buyRate (uint256): 1000000
Arg [4] : _sherlockPosition (address): 0x0865a889183039689034dA55c1Fd12aF5083eabF
Arg [5] : _receiver (address): 0x666B8EbFbF4D5f0CE56962a25635CfF563F13161
Arg [6] : _sherClaim (address): 0x7289C61C75dCdB8Fe4DF0b937c08c9c40902BDd3
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 00000000000000000000000046d2a90153cd8f09464ca3a5605b6bbec9c2ff01
Arg [1] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [2] : 0000000000000000000000000000000000000000000000000000000000895440
Arg [3] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [4] : 0000000000000000000000000865a889183039689034da55c1fd12af5083eabf
Arg [5] : 000000000000000000000000666b8ebfbf4d5f0ce56962a25635cff563f13161
Arg [6] : 0000000000000000000000007289c61c75dcdb8fe4df0b937c08c9c40902bdd3
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.