Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer Ownersh... | 21845962 | 26 days ago | IN | 0 ETH | 0.00004146 |
Latest 8 internal transactions
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
0x61026060 | 21988065 | 7 days ago | Contract Creation | 0 ETH | |||
0x61026060 | 21985245 | 7 days ago | Contract Creation | 0 ETH | |||
0x61026060 | 21906701 | 18 days ago | Contract Creation | 0 ETH | |||
Transfer* | 21902325 | 19 days ago | Contract Creation | 0 ETH | |||
0x61026060 | 21902285 | 19 days ago | Contract Creation | 0 ETH | |||
0x61026060 | 21862009 | 24 days ago | Contract Creation | 0 ETH | |||
0x61026060 | 21859670 | 25 days ago | Contract Creation | 0 ETH | |||
0x61026060 | 21852357 | 26 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
aspTKNMinimalOracleFactory
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.28; import "@openzeppelin/contracts/access/Ownable.sol"; import "./aspTKNMinimalOracle.sol"; contract aspTKNMinimalOracleFactory is Ownable { event Create(address newOracle); constructor() Ownable(_msgSender()) {} function create(address _aspTKN, bytes memory _requiredImmutables, bytes memory _optionalImmutables, uint96 _salt) external returns (address _oracleAddress) { _oracleAddress = _deploy(getBytecode(_aspTKN, _requiredImmutables, _optionalImmutables), _getFullSalt(_salt)); aspTKNMinimalOracle(_oracleAddress).transferOwnership(owner()); emit Create(_oracleAddress); } function getNewCaFromParams( address _aspTKN, bytes memory _requiredImmutables, bytes memory _optionalImmutables, uint96 _salt ) external view returns (address) { bytes memory _bytecode = getBytecode(_aspTKN, _requiredImmutables, _optionalImmutables); return getNewCaAddress(_bytecode, _salt); } function getBytecode(address _aspTKN, bytes memory _requiredImmutables, bytes memory _optionalImmutables) public pure returns (bytes memory) { bytes memory _bytecode = type(aspTKNMinimalOracle).creationCode; return abi.encodePacked(_bytecode, abi.encode(_aspTKN, _requiredImmutables, _optionalImmutables)); } function getNewCaAddress(bytes memory _bytecode, uint96 _salt) public view returns (address) { bytes32 _hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), _getFullSalt(_salt), keccak256(_bytecode))); return address(uint160(uint256(_hash))); } function _getFullSalt(uint96 _salt) internal view returns (uint256) { return uint256(uint160(address(this))) + _salt; } function _deploy(bytes memory _bytecode, uint256 _finalSalt) internal returns (address _addr) { assembly { _addr := create2(callvalue(), add(_bytecode, 0x20), mload(_bytecode), _finalSalt) if iszero(_addr) { revert(0, 0) } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.28; import "@openzeppelin/contracts/interfaces/IERC4626.sol"; import "./spTKNMinimalOracle.sol"; contract aspTKNMinimalOracle is spTKNMinimalOracle { address public immutable ASP_TKN; // QUOTE_TOKEN constructor(address _aspTKN, bytes memory _requiredImmutables, bytes memory _optionalImmutables) spTKNMinimalOracle(_requiredImmutables, _optionalImmutables) { ASP_TKN = _aspTKN; } function getPrices() public view virtual override returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh) { uint256 _assetFactor = 10 ** 18; uint256 _aspTknPerSpTkn = IERC4626(ASP_TKN).convertToShares(_assetFactor); (_isBadData, _priceLow, _priceHigh) = super.getPrices(); _priceLow = (_priceLow * _aspTknPerSpTkn) / _assetFactor; _priceHigh = (_priceHigh * _aspTknPerSpTkn) / _assetFactor; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol"; import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.28; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "../interfaces/IDecentralizedIndex.sol"; import "../interfaces/IFraxlendPair.sol"; import "../interfaces/IStakingPoolToken.sol"; import "../interfaces/IUniswapV2Pair.sol"; import "../interfaces/IMinimalOracle.sol"; import "../interfaces/ISPTknOracle.sol"; import "../interfaces/IMinimalSinglePriceOracle.sol"; import "../interfaces/IV2Reserves.sol"; contract spTKNMinimalOracle is IMinimalOracle, ISPTknOracle, Ownable { /// @dev The base token we will price against in the oracle. Will be either pairedLpAsset /// @dev or the borrow token in a lending pair address public immutable BASE_TOKEN; bool public immutable BASE_IS_POD; bool public immutable BASE_IS_FRAX_PAIR; address internal immutable BASE_IN_CL; /// @dev The concentrated liquidity UniV3 pool where we get the TWAP to price the underlying TKN /// @dev of the pod represented through spTkn and then convert it to the spTKN price address public immutable UNDERLYING_TKN_CL_POOL; /// @dev The Chainlink price feed we can use to convert the price we fetch through UNDERLYING_TKN_CL_POOL /// @dev into a BASE_TOKEN normalized price, /// @dev NOTE: primarily only needed if the paired token of the CL_POOL is not BASE_TOKEN address public immutable BASE_CONVERSION_CHAINLINK_FEED; address public immutable BASE_CONVERSION_CL_POOL; address public immutable BASE_CONVERSION_DIA_FEED; /// @dev Chainlink config to fetch a 2nd price for the oracle /// @dev The assumption would be that the paired asset of both oracles are the same /// @dev For example, if base=ETH, quote=BTC, the feeds we could use would be ETH/USD & BTC/USD address public immutable CHAINLINK_BASE_PRICE_FEED; address public immutable CHAINLINK_QUOTE_PRICE_FEED; /// @dev Single price oracle helpers to get already formatted prices that are easy to convert/use address public immutable CHAINLINK_SINGLE_PRICE_ORACLE; address public immutable UNISWAP_V3_SINGLE_PRICE_ORACLE; address public immutable DIA_SINGLE_PRICE_ORACLE; /// @dev Different networks will use different forked implementations of UniswapV2, so /// @dev this allows us to define a uniform interface to fetch the reserves of each asset in a pair IV2Reserves public immutable V2_RESERVES; /// @dev The pod staked LP token and oracle quote token that custodies UniV2 LP tokens address public spTkn; // QUOTE_TOKEN address public pod; address public underlyingTkn; uint32 twapInterval = 10 minutes; // errors error InvalidTwapInterval(); error NoPriceAvailableFromSources(); error NotValidSpTkn(); error OnlyOneOrNoBaseConversionsRequired(); error PodLocked(); error PrimaryOracleNotPresent(); error QuoteAndBaseChainlinkFeedsNotProvided(); error SpTknAlreadySet(); error UnableToPriceBasePerSpTkn(); // events event SetSpTknAndDependencies(address _pod); event SetTwapInterval(uint32 oldMax, uint32 newMax); constructor(bytes memory _requiredImmutables, bytes memory _optionalImmutables) Ownable(_msgSender()) { address _spTkn; address _v2Reserves; ( CHAINLINK_SINGLE_PRICE_ORACLE, UNISWAP_V3_SINGLE_PRICE_ORACLE, DIA_SINGLE_PRICE_ORACLE, BASE_TOKEN, BASE_IS_POD, BASE_IS_FRAX_PAIR, _spTkn, UNDERLYING_TKN_CL_POOL ) = abi.decode(_requiredImmutables, (address, address, address, address, bool, bool, address, address)); ( BASE_CONVERSION_CHAINLINK_FEED, BASE_CONVERSION_CL_POOL, BASE_CONVERSION_DIA_FEED, CHAINLINK_BASE_PRICE_FEED, CHAINLINK_QUOTE_PRICE_FEED, _v2Reserves ) = abi.decode(_optionalImmutables, (address, address, address, address, address, address)); V2_RESERVES = IV2Reserves(_v2Reserves); if ( UNDERLYING_TKN_CL_POOL == address(0) && CHAINLINK_BASE_PRICE_FEED == address(0) && CHAINLINK_QUOTE_PRICE_FEED == address(0) ) { revert PrimaryOracleNotPresent(); } if ( (CHAINLINK_QUOTE_PRICE_FEED != address(0) && CHAINLINK_BASE_PRICE_FEED == address(0)) || (CHAINLINK_QUOTE_PRICE_FEED == address(0) && CHAINLINK_BASE_PRICE_FEED != address(0)) ) { revert QuoteAndBaseChainlinkFeedsNotProvided(); } // only one (or neither) of the base conversion config should be populated address _baseConvFinal = BASE_CONVERSION_DIA_FEED != address(0) ? BASE_CONVERSION_DIA_FEED : BASE_CONVERSION_CL_POOL; if (BASE_CONVERSION_CHAINLINK_FEED != address(0) && _baseConvFinal != address(0)) { revert OnlyOneOrNoBaseConversionsRequired(); } address _baseInCl = BASE_TOKEN; if (BASE_IS_POD) { IDecentralizedIndex.IndexAssetInfo[] memory _baseAssets = IDecentralizedIndex(BASE_TOKEN).getAllAssets(); _baseInCl = _baseAssets[0].token; } else if (BASE_IS_FRAX_PAIR) { _baseInCl = IFraxlendPair(BASE_TOKEN).asset(); } BASE_IN_CL = _baseInCl; _setSpTknAndDependencies(_spTkn); } function getPodPerBasePrice() external view override returns (uint256 _pricePTknPerBase18) { _pricePTknPerBase18 = 10 ** (18 * 2) / _calculateBasePerPTkn(0); } /// @notice The ```getPrices``` function gets the mathematical price of spTkn / BASE_TOKEN, so in plain english will /// @notice be the number of spTkn per every BASE_TOKEN at 1e18 precision /// @return _isBadData Whether the price(s) returned should be considered bad /// @return _priceLow The lower of the dual prices returned /// @return _priceHigh The higher of the dual prices returned function getPrices() public view virtual override returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh) { uint256 _priceOne18; uint8 _baseDec = IERC20Metadata(BASE_TOKEN).decimals(); if (UNDERLYING_TKN_CL_POOL != address(0)) { uint256 _priceSpTKNBase = _calculateSpTknPerBase(0); _isBadData = _priceSpTKNBase == 0; _priceOne18 = _priceSpTKNBase * 10 ** (_baseDec > 18 ? _baseDec - 18 : 18 - _baseDec); } uint256 _priceTwo18 = _priceOne18; if (CHAINLINK_BASE_PRICE_FEED != address(0) && CHAINLINK_QUOTE_PRICE_FEED != address(0)) { uint256 _clPrice18 = _chainlinkBasePerPaired18(); uint256 _clPriceBaseSpTKN = _calculateSpTknPerBase(_clPrice18); _priceTwo18 = _clPriceBaseSpTKN * 10 ** (_baseDec > 18 ? _baseDec - 18 : 18 - _baseDec); _isBadData = _isBadData || _clPrice18 == 0; } if (_priceOne18 == 0 && _priceTwo18 == 0) { revert NoPriceAvailableFromSources(); } if (_priceOne18 == 0) { _priceLow = _priceTwo18; _priceHigh = _priceTwo18; } else if (_priceTwo18 == 0) { _priceLow = _priceOne18; _priceHigh = _priceOne18; } else { // If the prices are the same it means the CL price was pulled as the UniV3 price (_priceLow, _priceHigh) = _priceOne18 > _priceTwo18 ? (_priceTwo18, _priceOne18) : (_priceOne18, _priceTwo18); } } function _calculateSpTknPerBase(uint256 _price18) internal view returns (uint256 _spTknBasePrice18) { uint256 _priceBasePerPTkn18 = _calculateBasePerPTkn(_price18); address _pair = _getPair(); (uint112 _reserve0, uint112 _reserve1) = V2_RESERVES.getReserves(_pair); uint256 _k = uint256(_reserve0) * _reserve1; uint256 _kDec = 10 ** IERC20Metadata(IUniswapV2Pair(_pair).token0()).decimals() * 10 ** IERC20Metadata(IUniswapV2Pair(_pair).token1()).decimals(); uint256 _avgBaseAssetInLp27 = _sqrt((_priceBasePerPTkn18 * _k) / _kDec) * 10 ** 18; uint256 _pairSupply = IERC20(_pair).totalSupply(); if (_pairSupply == 0) { return 0; } uint256 _basePerSpTkn27 = (2 * _avgBaseAssetInLp27 * 10 ** IERC20Metadata(_pair).decimals()) / _pairSupply; if (_basePerSpTkn27 == 0) { revert UnableToPriceBasePerSpTkn(); } _spTknBasePrice18 = 10 ** (27 + 18) / _basePerSpTkn27; // if the base asset is a pod, we will assume that the CL/chainlink pool(s) are // pricing the underlying asset of the base asset pod, and therefore we will // adjust the output price by CBR and unwrap fee for this pod for more accuracy and // better handling accounting for liquidation path if (BASE_IS_POD) { _spTknBasePrice18 = _checkAndHandleBaseTokenPodConfig(_spTknBasePrice18); } else if (BASE_IS_FRAX_PAIR) { _spTknBasePrice18 = IFraxlendPair(BASE_TOKEN).convertToAssets(_spTknBasePrice18); } } function _calculateBasePerPTkn(uint256 _price18) internal view returns (uint256 _basePerPTkn18) { // pull from UniV3 TWAP if passed as 0 if (_price18 == 0) { bool _isBadData; (_isBadData, _price18) = _getDefaultPrice18(); if (_isBadData) { return 0; } } _basePerPTkn18 = _accountForCBRInPrice(pod, underlyingTkn, _price18); // adjust current price for spTKN pod unwrap fee, which will end up making the end price // (spTKN per base) higher, meaning it will take more spTKN to equal the value // of base token. This will more accurately ensure healthy LTVs when lending since // a liquidation path will need to account for unwrap fees _basePerPTkn18 = _accountForUnwrapFeeInPrice(pod, _basePerPTkn18); } function _getDefaultPrice18() internal view returns (bool _isBadData, uint256 _price18) { (_isBadData, _price18) = IMinimalSinglePriceOracle(UNISWAP_V3_SINGLE_PRICE_ORACLE).getPriceUSD18( BASE_CONVERSION_CHAINLINK_FEED, underlyingTkn, UNDERLYING_TKN_CL_POOL, twapInterval ); if (_isBadData) { return (true, 0); } if (BASE_CONVERSION_DIA_FEED != address(0)) { (bool _subBadData, uint256 _baseConvPrice18) = IMinimalSinglePriceOracle(DIA_SINGLE_PRICE_ORACLE) .getPriceUSD18(address(0), BASE_IN_CL, BASE_CONVERSION_DIA_FEED, 0); if (_subBadData) { return (true, 0); } _price18 = (10 ** 18 * _price18) / _baseConvPrice18; } else if (BASE_CONVERSION_CL_POOL != address(0)) { (bool _subBadData, uint256 _baseConvPrice18) = IMinimalSinglePriceOracle(UNISWAP_V3_SINGLE_PRICE_ORACLE) .getPriceUSD18(address(0), BASE_IN_CL, BASE_CONVERSION_CL_POOL, twapInterval); if (_subBadData) { return (true, 0); } _price18 = (10 ** 18 * _price18) / _baseConvPrice18; } } // final price with pod as baseTkn = price * baseCbr / (1 - basePodWrapFee) function _checkAndHandleBaseTokenPodConfig(uint256 _currentPrice18) internal view returns (uint256 _finalPrice18) { _finalPrice18 = _accountForCBRInPrice(BASE_TOKEN, address(0), _currentPrice18); _finalPrice18 = (_finalPrice18 * 10000) / (10000 - IDecentralizedIndex(BASE_TOKEN).BOND_FEE()); } function _chainlinkBasePerPaired18() internal view returns (uint256 _price18) { (bool _isBadData, uint256 _basePerPaired18) = IMinimalSinglePriceOracle(CHAINLINK_SINGLE_PRICE_ORACLE) .getPriceUSD18(CHAINLINK_QUOTE_PRICE_FEED, CHAINLINK_BASE_PRICE_FEED, address(0), 0); if (_isBadData) { return 0; } _price18 = _basePerPaired18; } function _getPair() private view returns (address) { return IStakingPoolToken(spTkn).stakingToken(); } function _accountForCBRInPrice(address _pod, address _underlying, uint256 _amtUnderlying) internal view returns (uint256) { if (_underlying == address(0)) { IDecentralizedIndex.IndexAssetInfo[] memory _assets = IDecentralizedIndex(_pod).getAllAssets(); _underlying = _assets[0].token; } uint256 _pTknAmt = (_amtUnderlying * 10 ** IERC20Metadata(_pod).decimals()) / 10 ** IERC20Metadata(_underlying).decimals(); uint256 _assetConv; if (_pod == BASE_TOKEN && IDecentralizedIndex(_pod).isFlashMinting() == 1) { _assetConv = IDecentralizedIndex(_pod).convertToAssetsPreFlashMint(_pTknAmt); } else if (IDecentralizedIndex(_pod).unlocked() == 1) { _assetConv = IDecentralizedIndex(_pod).convertToAssets(_pTknAmt); } else { revert PodLocked(); } return (_assetConv * 10000) / (10000 - IDecentralizedIndex(_pod).DEBOND_FEE()); } function _accountForUnwrapFeeInPrice(address _pod, uint256 _currentPrice) internal view returns (uint256 _newPrice) { uint16 _unwrapFee = IDecentralizedIndex(_pod).DEBOND_FEE(); _newPrice = _currentPrice - (_currentPrice * _unwrapFee) / 10000; } function _sqrt(uint256 x) private pure returns (uint256 y) { uint256 z = (x + 1) / 2; y = x; while (z < y) { y = z; z = (x / z + z) / 2; } } function _setSpTknAndDependencies(address _spTkn) internal { if (address(_spTkn) == address(0)) { return; } if (address(spTkn) != address(0)) { revert SpTknAlreadySet(); } spTkn = _spTkn; pod = IStakingPoolToken(spTkn).INDEX_FUND(); IDecentralizedIndex.IndexAssetInfo[] memory _assets = IDecentralizedIndex(pod).getAllAssets(); underlyingTkn = _assets[0].token; emit SetSpTknAndDependencies(address(pod)); } function setSpTknAndDependencies(address _spTkn) external onlyOwner { if (address(_spTkn) == address(0)) { revert NotValidSpTkn(); } _setSpTknAndDependencies(_spTkn); } function setTwapInterval(uint32 _interval) external onlyOwner { if (_interval == 0) { revert InvalidTwapInterval(); } uint32 _oldInterval = twapInterval; twapInterval = _interval; emit SetTwapInterval(_oldInterval, _interval); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IDexAdapter.sol"; interface IDecentralizedIndex is IERC20 { enum IndexType { WEIGHTED, UNWEIGHTED } struct Config { address partner; uint256 debondCooldown; bool hasTransferTax; bool blacklistTKNpTKNPoolV2; // DEPRECATED: we should remove this in future versions } // all fees: 1 == 0.01%, 10 == 0.1%, 100 == 1% struct Fees { uint16 burn; uint16 bond; uint16 debond; uint16 buy; uint16 sell; uint16 partner; } struct IndexAssetInfo { address token; uint256 weighting; uint256 basePriceUSDX96; address c1; // arbitrary contract/address field we can use for an index uint256 q1; // arbitrary quantity/number field we can use for an index } /// @notice The ```Create``` event fires when a new decentralized index has been created /// @param newIdx The CA of the new index contract /// @param wallet The creator of the new index event Create(address indexed newIdx, address indexed wallet); /// @notice The ```FlashLoan``` event fires when someone flash loans assets from the pod /// @param executor The sender of the request /// @param recipient The recipient of the flashed funds /// @param token The token being flash loaned /// @param amount The amount of token to flash loan event FlashLoan(address indexed executor, address indexed recipient, address token, uint256 amount); /// @notice The ```FlashMint``` event fires when someone flash mints pTKN from the pod /// @param executor The sender of the request /// @param recipient The recipient of the flashed funds /// @param amount The amount of pTKN to flash mint event FlashMint(address indexed executor, address indexed recipient, uint256 amount); /// @notice The ```Initialize``` event fires when the new pod has been initialized, /// @notice which is at creation on some and in another txn for others (gas limits) /// @param wallet The wallet that initialized /// @param v2Pool The new UniV2 derivative pool that was created at initialization event Initialize(address indexed wallet, address v2Pool); /// @notice The ```Bond``` event fires when someone wraps into the pod which mints new pod tokens /// @param wallet The wallet that wrapped /// @param token The token that was used as a ref to wrap into, representing an underlying tkn /// @param amountTokensBonded Amount of underlying tkns used to wrap/bond /// @param amountTokensMinted Amount of new pod tokens (pTKN) minted event Bond(address indexed wallet, address indexed token, uint256 amountTokensBonded, uint256 amountTokensMinted); /// @notice The ```Debond``` event fires when someone unwraps from a pod and redeems underlying tkn(s) /// @param wallet The wallet that unwrapped/debond /// @param amountDebonded Amount of pTKNs burned/unwrapped event Debond(address indexed wallet, uint256 amountDebonded); /// @notice The ```AddLiquidity``` event fires when new liquidity (LP) for a pod is added /// @param wallet The wallet that added LP /// @param amountTokens Amount of pTKNs used for LP /// @param amountDAI Amount of pairedLpAsset used for LP event AddLiquidity(address indexed wallet, uint256 amountTokens, uint256 amountDAI); /// @notice The ```RemoveLiquidity``` event fires when LP is removed for a pod /// @param wallet The wallet that removed LP /// @param amountLiquidity Amount of liquidity removed event RemoveLiquidity(address indexed wallet, uint256 amountLiquidity); event SetPartner(address indexed wallet, address newPartner); event SetPartnerFee(address indexed wallet, uint16 newFee); function BOND_FEE() external view returns (uint16); function DEBOND_FEE() external view returns (uint16); function DEX_HANDLER() external view returns (IDexAdapter); function FLASH_FEE_AMOUNT_DAI() external view returns (uint256); function PAIRED_LP_TOKEN() external view returns (address); function config() external view returns (Config calldata); function fees() external view returns (Fees calldata); function unlocked() external view returns (uint8); function isFlashMinting() external view returns (uint8); function indexType() external view returns (IndexType); function created() external view returns (uint256); function lpStakingPool() external view returns (address); function lpRewardsToken() external view returns (address); function isAsset(address token) external view returns (bool); function getAllAssets() external view returns (IndexAssetInfo[] memory); function getInitialAmount(address sToken, uint256 sAmount, address tToken) external view returns (uint256); function processPreSwapFeesAndSwap() external; function totalAssets() external view returns (uint256 totalManagedAssets); function totalAssets(address asset) external view returns (uint256 totalManagedAssets); function convertToShares(uint256 assets) external view returns (uint256 shares); function convertToAssets(uint256 shares) external view returns (uint256 assets); function convertToAssetsPreFlashMint(uint256 shares) external view returns (uint256 assets); function setup() external; function bond(address token, uint256 amount, uint256 amountMintMin) external; function debond(uint256 amount, address[] memory token, uint8[] memory percentage) external; function addLiquidityV2(uint256 idxTokens, uint256 daiTokens, uint256 slippage, uint256 deadline) external returns (uint256); function removeLiquidityV2(uint256 lpTokens, uint256 minTokens, uint256 minDAI, uint256 deadline) external; function flash(address recipient, address token, uint256 amount, bytes calldata data) external; function flashMint(address recipient, uint256 amount, bytes calldata data) external; function setLpStakingPool(address lpStakingPool) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import {VaultAccount} from "../libraries/VaultAccount.sol"; interface IFraxlendPair is IERC20 { struct CurrentRateInfo { uint32 lastBlock; uint32 feeToProtocolRate; // Fee amount 1e5 precision uint64 lastTimestamp; uint64 ratePerSec; uint64 fullUtilizationRate; } struct ExchangeRateInfo { address oracle; uint32 maxOracleDeviation; // % of larger number, 1e5 precision uint184 lastTimestamp; uint256 lowExchangeRate; uint256 highExchangeRate; } function exchangeRateInfo() external view returns (ExchangeRateInfo memory); function totalBorrow() external view returns (VaultAccount memory); function asset() external view returns (address); function collateralContract() external view returns (address); function convertToAssets(uint256 shares) external view returns (uint256 assets); function convertToShares(uint256 assets) external view returns (uint256 shares); function userCollateralBalance(address user) external view returns (uint256); // amount of collateral each user is backed function userBorrowShares(address user) external view returns (uint256); // represents the shares held by individuals function previewAddInterest() external view returns ( uint256 _interestEarned, uint256 _feesAmount, uint256 _feesShare, CurrentRateInfo memory _newCurrentRateInfo, VaultAccount memory _totalAsset, VaultAccount memory _totalBorrow ); function addInterest(bool _returnAccounting) external returns (uint256, uint256, uint256, CurrentRateInfo memory, VaultAccount memory, VaultAccount memory); function updateExchangeRate() external returns (bool _isBorrowAllowed, uint256 _lowExchangeRate, uint256 _highExchangeRate); function deposit(uint256 _amount, address _receiver) external returns (uint256 _sharesReceived); function redeem(uint256 _shares, address _receiver, address _owner) external returns (uint256 _amountToReturn); function borrowAsset(uint256 _borrowAmount, uint256 _collateralAmount, address _receiver) external returns (uint256 _shares); function repayAsset(uint256 _shares, address _borrower) external returns (uint256 _amountToRepay); function addCollateral(uint256 _collateralAmount, address _borrower) external; function removeCollateral(uint256 _collateralAmount, address _receiver) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; interface IStakingPoolToken { event Stake(address indexed executor, address indexed user, uint256 amount); event Unstake(address indexed user, uint256 amount); function INDEX_FUND() external view returns (address); function POOL_REWARDS() external view returns (address); function stakingToken() external view returns (address); function stakeUserRestriction() external view returns (address); function stake(address user, uint256 amount) external; function unstake(uint256 amount) external; function setPoolRewards(address poolRewards) external; function setStakingToken(address stakingToken) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; interface IUniswapV2Pair { function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; interface IMinimalOracle { function getPrices() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; interface ISPTknOracle { function getPodPerBasePrice() external view returns (uint256 _price); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; interface IMinimalSinglePriceOracle { function getPriceUSD18( address base, address quote, address a1, // any extra address parameter an implementation may need uint256 q1 // any extra uint256 parameter an implementation may need ) external view returns (bool isBadData, uint256 price18); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; interface IV2Reserves { function getReserves(address _pair) external view returns (uint112 reserve0, uint112 reserve1); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; interface IDexAdapter { function ASYNC_INITIALIZE() external view returns (bool); function V2_ROUTER() external view returns (address); function V3_ROUTER() external view returns (address); function WETH() external view returns (address); function getV3Pool(address _token0, address _token1, int24 _tickSpacing) external view returns (address _pool); function getV3Pool(address _token0, address _token1, uint24 _poolFee) external view returns (address _pool); function getV2Pool(address _token0, address _token1) external view returns (address _pool); function createV2Pool(address _token0, address _token1) external returns (address _pool); function getReserves(address _pool) external view returns (uint112, uint112); function swapV2Single( address _tokenIn, address _tokenOut, uint256 _amountIn, uint256 _amountOutMin, address _recipient ) external returns (uint256 _amountOut); function swapV2SingleExactOut( address _tokenIn, address _tokenOut, uint256 _amountInMax, uint256 _amountOut, address _recipient ) external returns (uint256 _amountInUsed); function swapV3Single( address _tokenIn, address _tokenOut, uint24 _fee, uint256 _amountIn, uint256 _amountOutMin, address _recipient ) external returns (uint256 _amountOut); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external; function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: ISC pragma solidity ^0.8.28; struct VaultAccount { uint128 amount; // Total amount, analogous to market cap uint128 shares; // Total shares, analogous to shares outstanding } /// @title VaultAccount Library /// @author Drake Evans (Frax Finance) github.com/drakeevans, modified from work by @Boring_Crypto github.com/boring_crypto /// @notice Provides a library for use with the VaultAccount struct, provides convenient math implementations /// @dev Uses uint128 to save on storage library VaultAccountingLibrary { /// @notice Calculates the shares value in relationship to `amount` and `total` /// @dev Given an amount, return the appropriate number of shares function toShares(VaultAccount memory total, uint256 amount, bool roundUp) internal pure returns (uint256 shares) { if (total.amount == 0) { shares = amount; } else { shares = (amount * total.shares) / total.amount; if (roundUp && (shares * total.amount) / total.shares < amount) { shares = shares + 1; } } } /// @notice Calculates the amount value in relationship to `shares` and `total` /// @dev Given a number of shares, returns the appropriate amount function toAmount(VaultAccount memory total, uint256 shares, bool roundUp) internal pure returns (uint256 amount) { if (total.shares == 0) { amount = shares; } else { amount = (shares * total.amount) / total.shares; if (roundUp && (amount * total.shares) / total.amount < shares) { amount = amount + 1; } } } }
{ "remappings": [ "@chainlink/=node_modules/@chainlink/", "@fraxlend/=test/invariant/modules/fraxlend/", "fuzzlib/=lib/fuzzlib/src/", "swap-router/=test/invariant/modules/v3-periphery/swapRouter/", "v3-core/=test/invariant/modules/v3-core/", "v3-periphery/=test/invariant/modules/v3-periphery/", "v2-core/=test/invariant/modules/uniswap-v2/v2-core/contracts/", "v2-periphery/=test/invariant/modules/uniswap-v2/v2-periphery/contracts/", "uniswap-v2/=test/invariant/modules/uniswap-v2/", "solidity-bytes-utils/contracts/=test/invariant/modules/fraxlend/libraries/", "@rari-capital/solmate/=node_modules/solmate/", "@arbitrum/=node_modules/@arbitrum/", "@ensdomains/=node_modules/@ensdomains/", "@eth-optimism/=node_modules/@eth-optimism/", "@ethereum-waffle/=node_modules/@ethereum-waffle/", "@mean-finance/=node_modules/@mean-finance/", "@offchainlabs/=node_modules/@offchainlabs/", "@openzeppelin/=node_modules/@openzeppelin/", "@scroll-tech/=node_modules/@scroll-tech/", "@uniswap/=node_modules/@uniswap/", "@zksync/=node_modules/@zksync/", "base64-sol/=node_modules/base64-sol/", "ds-test/=lib/fuzzlib/lib/forge-std/lib/ds-test/src/", "erc721a/=node_modules/erc721a/", "eth-gas-reporter/=node_modules/eth-gas-reporter/", "forge-std/=lib/forge-std/src/", "hardhat/=node_modules/hardhat/", "solidity-code-metrics/=node_modules/solidity-code-metrics/", "solmate/=node_modules/solmate/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOracle","type":"address"}],"name":"Create","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"_aspTKN","type":"address"},{"internalType":"bytes","name":"_requiredImmutables","type":"bytes"},{"internalType":"bytes","name":"_optionalImmutables","type":"bytes"},{"internalType":"uint96","name":"_salt","type":"uint96"}],"name":"create","outputs":[{"internalType":"address","name":"_oracleAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_aspTKN","type":"address"},{"internalType":"bytes","name":"_requiredImmutables","type":"bytes"},{"internalType":"bytes","name":"_optionalImmutables","type":"bytes"}],"name":"getBytecode","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_bytecode","type":"bytes"},{"internalType":"uint96","name":"_salt","type":"uint96"}],"name":"getNewCaAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_aspTKN","type":"address"},{"internalType":"bytes","name":"_requiredImmutables","type":"bytes"},{"internalType":"bytes","name":"_optionalImmutables","type":"bytes"},{"internalType":"uint96","name":"_salt","type":"uint96"}],"name":"getNewCaFromParams","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052348015600f57600080fd5b503380603557604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b603c816041565b506091565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61322d806100a06000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100dc578063a1458ce5146100ed578063c644661814610100578063f2fde38b1461011357600080fd5b80633691bbf01461008257806349815834146100b2578063715018a6146100d2575b600080fd5b610095610090366004610516565b610126565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c56100c03660046105a0565b61014a565b6040516100a99190610669565b6100da6101c1565b005b6000546001600160a01b0316610095565b6100956100fb366004610516565b6101d5565b61009561010e366004610683565b6102b4565b6100da6101213660046106d1565b61033b565b60008061013486868661014a565b905061014081846102b4565b9695505050505050565b606060006040518060200161015e9061042c565b6020820181038252601f19601f8201166040525090508085858560405160200161018a939291906106ec565b60408051601f19818403018152908290526101a89291602001610722565b6040516020818303038152906040529150509392505050565b6101c961037e565b6101d360006103ab565b565b60006101f36101e586868661014a565b6101ee846103fb565b610415565b9050806001600160a01b031663f2fde38b6102166000546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b15801561025757600080fd5b505af115801561026b573d6000803e3d6000fd5b50506040516001600160a01b03841681527fe3758539c1bd6726422843471b2886c2d2cefd3b4aead6778386283e20a32a809250602001905060405180910390a1949350505050565b6000806001600160f81b0319306102ca856103fb565b868051906020012060405160200161031994939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f1981840301815291905280516020909101209150505b92915050565b61034361037e565b6001600160a01b03811661037257604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b61037b816103ab565b50565b6000546001600160a01b031633146101d35760405163118cdaa760e01b8152336004820152602401610369565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006103356bffffffffffffffffffffffff831630610751565b60008183516020850134f590508061033557600080fd5b612a858061077383390190565b80356001600160a01b038116811461045057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261047c57600080fd5b813567ffffffffffffffff81111561049657610496610455565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156104c5576104c5610455565b6040528181528382016020018510156104dd57600080fd5b816020850160208301376000918101602001919091529392505050565b80356bffffffffffffffffffffffff8116811461045057600080fd5b6000806000806080858703121561052c57600080fd5b61053585610439565b9350602085013567ffffffffffffffff81111561055157600080fd5b61055d8782880161046b565b935050604085013567ffffffffffffffff81111561057a57600080fd5b6105868782880161046b565b925050610595606086016104fa565b905092959194509250565b6000806000606084860312156105b557600080fd5b6105be84610439565b9250602084013567ffffffffffffffff8111156105da57600080fd5b6105e68682870161046b565b925050604084013567ffffffffffffffff81111561060357600080fd5b61060f8682870161046b565b9150509250925092565b60005b8381101561063457818101518382015260200161061c565b50506000910152565b60008151808452610655816020860160208601610619565b601f01601f19169290920160200192915050565b60208152600061067c602083018461063d565b9392505050565b6000806040838503121561069657600080fd5b823567ffffffffffffffff8111156106ad57600080fd5b6106b98582860161046b565b9250506106c8602084016104fa565b90509250929050565b6000602082840312156106e357600080fd5b61067c82610439565b6001600160a01b03841681526060602082018190526000906107109083018561063d565b8281036040840152610140818561063d565b60008351610734818460208801610619565b835190830190610748818360208801610619565b01949350505050565b8082018082111561033557634e487b7160e01b600052601160045260246000fdfe6102606040526003805463ffffffff60a01b1916604b60a31b17905534801561002757600080fd5b50604051612a85380380612a8583398101604081905261004691610683565b8181338061006e57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61007781610375565b506000808380602001905181019061008f9190610714565b6001600160a01b039081166101005291151560c05291151560a052918216608052918116610200529182166101e05291166101c05283519092506100dc90840160209081019085016107bd565b6001600160a01b039182166101a0529181166101805291821661016052918116610140529182166101205281811661022052610100519092501615801561012d5750610180516001600160a01b0316155b801561014357506101a0516001600160a01b0316155b156101615760405163e50103e760e01b815260040160405180910390fd5b6101a0516001600160a01b0316158015906101865750610180516001600160a01b0316155b806101b157506101a0516001600160a01b03161580156101b15750610180516001600160a01b031615155b156101cf576040516328628d9560e21b815260040160405180910390fd5b610160516000906001600160a01b03166101ec57610140516101f1565b610160515b610120519091506001600160a01b03161580159061021757506001600160a01b03811615155b1561023557604051634b26727360e11b815260040160405180910390fd5b60805160a051156102d35760006080516001600160a01b0316632acada4d6040518163ffffffff1660e01b8152600401600060405180830381865afa158015610282573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102aa9190810190610844565b9050806000815181106102bf576102bf610949565b602002602001015160000151915050610342565b60c05115610342576080516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561031b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033f919061095f565b90505b6001600160a01b03811660e052610358846103c5565b5050506001600160a01b0390951661024052506109839350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381166103d65750565b6001546001600160a01b03161561040057604051634af85cf560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560408051632aa6a85160e21b8152905163aa9aa144916004808201926020929091908290030181865afa158015610459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047d919061095f565b600280546001600160a01b0319166001600160a01b0392909216918217905560408051632acada4d60e01b8152905160009291632acada4d91600480830192869291908290030181865afa1580156104d9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105019190810190610844565b90508060008151811061051657610516610949565b60209081029190910181015151600380546001600160a01b0319166001600160a01b03928316179055600254604051911681527f02176273ef1668d41059376b23ac9b35710fdc7c4f5672098d43162c71b88cc2910160405180910390a15050565b6001600160a01b038116811461058d57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156105c8576105c8610590565b60405290565b604051601f8201601f191681016001600160401b03811182821017156105f6576105f6610590565b604052919050565b600082601f83011261060f57600080fd5b81516001600160401b0381111561062857610628610590565b61063b601f8201601f19166020016105ce565b81815284602083860101111561065057600080fd5b60005b8281101561066f57602081860181015183830182015201610653565b506000918101602001919091529392505050565b60008060006060848603121561069857600080fd5b83516106a381610578565b60208501519093506001600160401b038111156106bf57600080fd5b6106cb868287016105fe565b604086015190935090506001600160401b038111156106e957600080fd5b6106f5868287016105fe565b9150509250925092565b8051801515811461070f57600080fd5b919050565b600080600080600080600080610100898b03121561073157600080fd5b885161073c81610578565b60208a015190985061074d81610578565b60408a015190975061075e81610578565b60608a015190965061076f81610578565b945061077d60808a016106ff565b935061078b60a08a016106ff565b925060c089015161079b81610578565b60e08a01519092506107ac81610578565b809150509295985092959890939650565b60008060008060008060c087890312156107d657600080fd5b86516107e181610578565b60208801519096506107f281610578565b604088015190955061080381610578565b606088015190945061081481610578565b608088015190935061082581610578565b60a088015190925061083681610578565b809150509295509295509295565b60006020828403121561085657600080fd5b81516001600160401b0381111561086c57600080fd5b8201601f8101841361087d57600080fd5b80516001600160401b0381111561089657610896610590565b6108a560208260051b016105ce565b80828252602082019150602060a084028501019250868311156108c757600080fd5b6020840193505b8284101561093f5760a084880312156108e657600080fd5b6108ee6105a6565b84516108f981610578565b81526020858101519082015260408086015190820152606085015161091d81610578565b606082015260808581015190820152825260a0909301926020909101906108ce565b9695505050505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561097157600080fd5b815161097c81610578565b9392505050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e051610200516102205161024051611fa1610ae460003960008181610192015261057b0152600081816102f6015261139e01526000818161021e0152610d3101526000818161041801528181610c060152610e8f01526000818161036901526118ce01526000818161043f015281816108cb01526118690152600081816103b701528181610898015261189101526000818161039001528181610c890152610cfe01526000818161031d01528181610dd90152610e510152600081816102450152610b8d0152600081816102bc015281816108170152610bc6015260008181610cd60152610e2901526000818161027401526117940152600081816103f1015261175e0152600081816101e1015281816107930152818161106e015281816117ce01528181611a1b0152611a460152611fa16000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063a88dbb36116100c3578063cdbb0e691161007c578063cdbb0e69146103b2578063cf5aae19146103d9578063d401178e146103ec578063eb33bd3c14610413578063ef88dac11461043a578063f2fde38b1461046157600080fd5b8063a88dbb36146102de578063aa0effc5146102f1578063b235c94b14610318578063bd9a548b1461033f578063ca5ed14c14610364578063cc8825011461038b57600080fd5b806343ed99111161011557806343ed99111461021957806346eeb01a14610240578063715018a61461026757806385295c491461026f5780638da5cb5b146102a65780638dd79417146102b757600080fd5b80630738831b1461015d578063163f2c541461018d57806318f932c2146101b45780631d27050f146101c7578063210663e4146101dc578063329ea9b114610203575b600080fd5b600154610170906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101707f000000000000000000000000000000000000000000000000000000000000000081565b600354610170906001600160a01b031681565b6101da6101d5366004611aec565b610474565b005b6101707f000000000000000000000000000000000000000000000000000000000000000081565b61020b61050d565b604051908152602001610184565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101da610537565b6102967f000000000000000000000000000000000000000000000000000000000000000081565b6040519015158152602001610184565b6000546001600160a01b0316610170565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b600254610170906001600160a01b031681565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b61034761054b565b604080519315158452602084019290925290820152606001610184565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101da6103e7366004611b2e565b61062c565b6102967f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101da61046f366004611b2e565b610667565b61047c6106a7565b8063ffffffff166000036104a35760405163cad929df60e01b815260040160405180910390fd5b6003805463ffffffff838116600160a01b81810263ffffffff60a01b1985161790945560408051949093049091168084526020840191909152917f86139943149914833c057d2c24f3a3967cce8e6aba2eb12e422500d8a51ffc7b91015b60405180910390a15050565b600061051960006106d4565b610532906ec097ce7bc90715b34b9f1000000000611b61565b905090565b61053f6106a7565b6105496000610739565b565b6040516363737ac960e11b8152670de0b6b3a7640000600482018190526000918291829182906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c6e6f59290602401602060405180830381865afa1580156105c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e69190611b83565b90506105f0610789565b91965094509250816106028286611b9c565b61060c9190611b61565b9350816106198285611b9c565b6106239190611b61565b92505050909192565b6106346106a7565b6001600160a01b03811661065b57604051631b1689ab60e11b815260040160405180910390fd5b610664816109cf565b50565b61066f6106a7565b6001600160a01b03811661069e57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b61066481610739565b6000546001600160a01b031633146105495760405163118cdaa760e01b8152336004820152602401610695565b6000816000036106fd5760006106e8610b7b565b9350905080156106fb5750600092915050565b505b60025460035461071a916001600160a01b03908116911684610edb565b600254909150610733906001600160a01b0316826112cb565b92915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108139190611bb3565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615610895576000610850600061135f565b801596509050601260ff8316116108715761086c826012611bd6565b61087c565b61087c601283611bd6565b61088790600a611cd6565b6108919082611b9c565b9250505b817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158015906108f657507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15610960576000610905611852565b905060006109128261135f565b905060128460ff161161092f5761092a846012611bd6565b61093a565b61093a601285611bd6565b61094590600a611cd6565b61094f9082611b9c565b9250878061095b575081155b975050505b8215801561096c575080155b1561098a5760405163340d2cbf60e11b815260040160405180910390fd5b8260000361099d578094508093506109c7565b806000036109b0578294508293506109c7565b8083116109be5782816109c1565b80835b90955093505b505050909192565b6001600160a01b0381166109e05750565b6001546001600160a01b031615610a0a57604051634af85cf560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560408051632aa6a85160e21b8152905163aa9aa144916004808201926020929091908290030181865afa158015610a63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a879190611ce5565b600280546001600160a01b0319166001600160a01b0392909216918217905560408051632acada4d60e01b8152905160009291632acada4d91600480830192869291908290030181865afa158015610ae3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b0b9190810190611d72565b905080600081518110610b2057610b20611e6f565b60209081029190910181015151600380546001600160a01b0319166001600160a01b03928316179055600254604051911681527f02176273ef1668d41059376b23ac9b35710fdc7c4f5672098d43162c71b88cc29101610501565b600354604051630807aa9160e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03908116600483015280831660248301527f000000000000000000000000000000000000000000000000000000000000000081166044830152600160a01b90920463ffffffff16606482015260009182917f000000000000000000000000000000000000000000000000000000000000000090911690630807aa91906084016040805180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c729190611e85565b90925090508115610c87575060019160009150565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615610dd757604051630807aa9160e01b81526000600482018190526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248401527f00000000000000000000000000000000000000000000000000000000000000008116604484015260648301829052909182917f00000000000000000000000000000000000000000000000000000000000000001690630807aa91906084016040805180830381865afa158015610d77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9b9190611e85565b915091508115610db2575060019360009350915050565b80610dc584670de0b6b3a7640000611b9c565b610dcf9190611b61565b925050509091565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615610ed757600354604051630807aa9160e01b81526000600482018190526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248401527f000000000000000000000000000000000000000000000000000000000000000081166044840152600160a01b90930463ffffffff1660648301529182917f000000000000000000000000000000000000000000000000000000000000000090911690630807aa91906084016040805180830381865afa158015610d77573d6000803e3d6000fd5b9091565b60006001600160a01b038316610f78576000846001600160a01b0316632acada4d6040518163ffffffff1660e01b8152600401600060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f539190810190611d72565b905080600081518110610f6857610f68611e6f565b6020026020010151600001519350505b6000836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdc9190611bb3565b610fe790600a611cd6565b856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110499190611bb3565b61105490600a611cd6565b61105e9085611b9c565b6110689190611b61565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03161480156111115750856001600160a01b0316635ca8861f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110a9190611bb3565b60ff166001145b15611187576040516359339af360e11b8152600481018390526001600160a01b0387169063b26735e6906024015b602060405180830381865afa15801561115c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111809190611b83565b9050611239565b856001600160a01b0316636a5e26506040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e99190611bb3565b60ff16600103611220576040516303d1689d60e11b8152600481018390526001600160a01b038716906307a2d13a9060240161113f565b604051634f10a27f60e11b815260040160405180910390fd5b856001600160a01b031663bdc8d0606040518163ffffffff1660e01b8152600401602060405180830381865afa158015611277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129b9190611eb8565b6112a790612710611edc565b61ffff166112b782612710611b9c565b6112c19190611b61565b9695505050505050565b600080836001600160a01b031663bdc8d0606040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113309190611eb8565b905061271061134361ffff831685611b9c565b61134d9190611b61565b6113579084611ef6565b949350505050565b60008061136b836106d4565b9050600061137761194d565b604051630fa6707960e21b81526001600160a01b03828116600483015291925060009182917f000000000000000000000000000000000000000000000000000000000000000090911690633e99c1e4906024016040805180830381865afa1580156113e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140a9190611f25565b915091506000816001600160701b0316836001600160701b031661142e9190611b9c565b90506000846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114949190611ce5565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f59190611bb3565b61150090600a611cd6565b856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561153e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115629190611ce5565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561159f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c39190611bb3565b6115ce90600a611cd6565b6115d89190611b9c565b905060006115f9826115ea858a611b9c565b6115f49190611b61565b6119bb565b61160b90670de0b6b3a7640000611b9c565b90506000866001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561164d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116719190611b83565b90508060000361168b575060009998505050505050505050565b600081886001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f09190611bb3565b6116fb90600a611cd6565b611706856002611b9c565b6117109190611b9c565b61171a9190611b61565b90508060000361173d5760405163e9c8240960e01b815260040160405180910390fd5b61175a81722cd76fe086b93ce2f768a00b22a00000000000611b61565b99507f0000000000000000000000000000000000000000000000000000000000000000156117925761178b8a611a14565b9950611844565b7f000000000000000000000000000000000000000000000000000000000000000015611844576040516303d1689d60e11b8152600481018b90527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307a2d13a90602401602060405180830381865afa15801561181d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118419190611b83565b99505b505050505050505050919050565b604051630807aa9160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000811660248301526000604483018190526064830181905291829182917f000000000000000000000000000000000000000000000000000000000000000090911690630807aa91906084016040805180830381865afa158015611916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193a9190611e85565b9150915081156107335760009250505090565b600154604080516372f702f360e01b815290516000926001600160a01b0316916372f702f39160048083019260209291908290030181865afa158015611997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105329190611ce5565b60008060026119cb846001611f58565b6119d59190611b61565b90508291505b81811015611a0e579050806002816119f38186611b61565b6119fd9190611f58565b611a079190611b61565b90506119db565b50919050565b6000611a427f0000000000000000000000000000000000000000000000000000000000000000600084610edb565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ff140ca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac69190611eb8565b611ad290612710611edc565b61ffff16611ae282612710611b9c565b6107339190611b61565b600060208284031215611afe57600080fd5b813563ffffffff81168114611b1257600080fd5b9392505050565b6001600160a01b038116811461066457600080fd5b600060208284031215611b4057600080fd5b8135611b1281611b19565b634e487b7160e01b600052601160045260246000fd5b600082611b7e57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215611b9557600080fd5b5051919050565b808202811582820484141761073357610733611b4b565b600060208284031215611bc557600080fd5b815160ff81168114611b1257600080fd5b60ff828116828216039081111561073357610733611b4b565b6001815b6001841115611c2a57808504811115611c0e57611c0e611b4b565b6001841615611c1c57908102905b60019390931c928002611bf3565b935093915050565b600082611c4157506001610733565b81611c4e57506000610733565b8160018114611c645760028114611c6e57611c8a565b6001915050610733565b60ff841115611c7f57611c7f611b4b565b50506001821b610733565b5060208310610133831016604e8410600b8410161715611cad575081810a610733565b611cba6000198484611bef565b8060001904821115611cce57611cce611b4b565b029392505050565b6000611b1260ff841683611c32565b600060208284031215611cf757600080fd5b8151611b1281611b19565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715611d3b57611d3b611d02565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611d6a57611d6a611d02565b604052919050565b600060208284031215611d8457600080fd5b815167ffffffffffffffff811115611d9b57600080fd5b8201601f81018413611dac57600080fd5b805167ffffffffffffffff811115611dc657611dc6611d02565b611dd560208260051b01611d41565b80828252602082019150602060a08402850101925086831115611df757600080fd5b6020840193505b828410156112c15760a08488031215611e1657600080fd5b611e1e611d18565b8451611e2981611b19565b815260208581015190820152604080860151908201526060850151611e4d81611b19565b606082015260808581015190820152825260a090930192602090910190611dfe565b634e487b7160e01b600052603260045260246000fd5b60008060408385031215611e9857600080fd5b82518015158114611ea857600080fd5b6020939093015192949293505050565b600060208284031215611eca57600080fd5b815161ffff81168114611b1257600080fd5b61ffff828116828216039081111561073357610733611b4b565b8181038181111561073357610733611b4b565b80516001600160701b0381168114611f2057600080fd5b919050565b60008060408385031215611f3857600080fd5b611f4183611f09565b9150611f4f60208401611f09565b90509250929050565b8082018082111561073357610733611b4b56fea2646970667358221220536fedd0b2727cdaed7826318acbb5e61a1ebb18e77a623c63a82effae16796464736f6c634300081c0033a2646970667358221220d4fb90d407594481977da921d721c1f8907f1996885e11675ffbb5b06d2c5c3e64736f6c634300081c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100dc578063a1458ce5146100ed578063c644661814610100578063f2fde38b1461011357600080fd5b80633691bbf01461008257806349815834146100b2578063715018a6146100d2575b600080fd5b610095610090366004610516565b610126565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c56100c03660046105a0565b61014a565b6040516100a99190610669565b6100da6101c1565b005b6000546001600160a01b0316610095565b6100956100fb366004610516565b6101d5565b61009561010e366004610683565b6102b4565b6100da6101213660046106d1565b61033b565b60008061013486868661014a565b905061014081846102b4565b9695505050505050565b606060006040518060200161015e9061042c565b6020820181038252601f19601f8201166040525090508085858560405160200161018a939291906106ec565b60408051601f19818403018152908290526101a89291602001610722565b6040516020818303038152906040529150509392505050565b6101c961037e565b6101d360006103ab565b565b60006101f36101e586868661014a565b6101ee846103fb565b610415565b9050806001600160a01b031663f2fde38b6102166000546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b15801561025757600080fd5b505af115801561026b573d6000803e3d6000fd5b50506040516001600160a01b03841681527fe3758539c1bd6726422843471b2886c2d2cefd3b4aead6778386283e20a32a809250602001905060405180910390a1949350505050565b6000806001600160f81b0319306102ca856103fb565b868051906020012060405160200161031994939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f1981840301815291905280516020909101209150505b92915050565b61034361037e565b6001600160a01b03811661037257604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b61037b816103ab565b50565b6000546001600160a01b031633146101d35760405163118cdaa760e01b8152336004820152602401610369565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006103356bffffffffffffffffffffffff831630610751565b60008183516020850134f590508061033557600080fd5b612a858061077383390190565b80356001600160a01b038116811461045057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261047c57600080fd5b813567ffffffffffffffff81111561049657610496610455565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156104c5576104c5610455565b6040528181528382016020018510156104dd57600080fd5b816020850160208301376000918101602001919091529392505050565b80356bffffffffffffffffffffffff8116811461045057600080fd5b6000806000806080858703121561052c57600080fd5b61053585610439565b9350602085013567ffffffffffffffff81111561055157600080fd5b61055d8782880161046b565b935050604085013567ffffffffffffffff81111561057a57600080fd5b6105868782880161046b565b925050610595606086016104fa565b905092959194509250565b6000806000606084860312156105b557600080fd5b6105be84610439565b9250602084013567ffffffffffffffff8111156105da57600080fd5b6105e68682870161046b565b925050604084013567ffffffffffffffff81111561060357600080fd5b61060f8682870161046b565b9150509250925092565b60005b8381101561063457818101518382015260200161061c565b50506000910152565b60008151808452610655816020860160208601610619565b601f01601f19169290920160200192915050565b60208152600061067c602083018461063d565b9392505050565b6000806040838503121561069657600080fd5b823567ffffffffffffffff8111156106ad57600080fd5b6106b98582860161046b565b9250506106c8602084016104fa565b90509250929050565b6000602082840312156106e357600080fd5b61067c82610439565b6001600160a01b03841681526060602082018190526000906107109083018561063d565b8281036040840152610140818561063d565b60008351610734818460208801610619565b835190830190610748818360208801610619565b01949350505050565b8082018082111561033557634e487b7160e01b600052601160045260246000fdfe6102606040526003805463ffffffff60a01b1916604b60a31b17905534801561002757600080fd5b50604051612a85380380612a8583398101604081905261004691610683565b8181338061006e57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61007781610375565b506000808380602001905181019061008f9190610714565b6001600160a01b039081166101005291151560c05291151560a052918216608052918116610200529182166101e05291166101c05283519092506100dc90840160209081019085016107bd565b6001600160a01b039182166101a0529181166101805291821661016052918116610140529182166101205281811661022052610100519092501615801561012d5750610180516001600160a01b0316155b801561014357506101a0516001600160a01b0316155b156101615760405163e50103e760e01b815260040160405180910390fd5b6101a0516001600160a01b0316158015906101865750610180516001600160a01b0316155b806101b157506101a0516001600160a01b03161580156101b15750610180516001600160a01b031615155b156101cf576040516328628d9560e21b815260040160405180910390fd5b610160516000906001600160a01b03166101ec57610140516101f1565b610160515b610120519091506001600160a01b03161580159061021757506001600160a01b03811615155b1561023557604051634b26727360e11b815260040160405180910390fd5b60805160a051156102d35760006080516001600160a01b0316632acada4d6040518163ffffffff1660e01b8152600401600060405180830381865afa158015610282573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102aa9190810190610844565b9050806000815181106102bf576102bf610949565b602002602001015160000151915050610342565b60c05115610342576080516001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561031b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033f919061095f565b90505b6001600160a01b03811660e052610358846103c5565b5050506001600160a01b0390951661024052506109839350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381166103d65750565b6001546001600160a01b03161561040057604051634af85cf560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560408051632aa6a85160e21b8152905163aa9aa144916004808201926020929091908290030181865afa158015610459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047d919061095f565b600280546001600160a01b0319166001600160a01b0392909216918217905560408051632acada4d60e01b8152905160009291632acada4d91600480830192869291908290030181865afa1580156104d9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105019190810190610844565b90508060008151811061051657610516610949565b60209081029190910181015151600380546001600160a01b0319166001600160a01b03928316179055600254604051911681527f02176273ef1668d41059376b23ac9b35710fdc7c4f5672098d43162c71b88cc2910160405180910390a15050565b6001600160a01b038116811461058d57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156105c8576105c8610590565b60405290565b604051601f8201601f191681016001600160401b03811182821017156105f6576105f6610590565b604052919050565b600082601f83011261060f57600080fd5b81516001600160401b0381111561062857610628610590565b61063b601f8201601f19166020016105ce565b81815284602083860101111561065057600080fd5b60005b8281101561066f57602081860181015183830182015201610653565b506000918101602001919091529392505050565b60008060006060848603121561069857600080fd5b83516106a381610578565b60208501519093506001600160401b038111156106bf57600080fd5b6106cb868287016105fe565b604086015190935090506001600160401b038111156106e957600080fd5b6106f5868287016105fe565b9150509250925092565b8051801515811461070f57600080fd5b919050565b600080600080600080600080610100898b03121561073157600080fd5b885161073c81610578565b60208a015190985061074d81610578565b60408a015190975061075e81610578565b60608a015190965061076f81610578565b945061077d60808a016106ff565b935061078b60a08a016106ff565b925060c089015161079b81610578565b60e08a01519092506107ac81610578565b809150509295985092959890939650565b60008060008060008060c087890312156107d657600080fd5b86516107e181610578565b60208801519096506107f281610578565b604088015190955061080381610578565b606088015190945061081481610578565b608088015190935061082581610578565b60a088015190925061083681610578565b809150509295509295509295565b60006020828403121561085657600080fd5b81516001600160401b0381111561086c57600080fd5b8201601f8101841361087d57600080fd5b80516001600160401b0381111561089657610896610590565b6108a560208260051b016105ce565b80828252602082019150602060a084028501019250868311156108c757600080fd5b6020840193505b8284101561093f5760a084880312156108e657600080fd5b6108ee6105a6565b84516108f981610578565b81526020858101519082015260408086015190820152606085015161091d81610578565b606082015260808581015190820152825260a0909301926020909101906108ce565b9695505050505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561097157600080fd5b815161097c81610578565b9392505050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e051610200516102205161024051611fa1610ae460003960008181610192015261057b0152600081816102f6015261139e01526000818161021e0152610d3101526000818161041801528181610c060152610e8f01526000818161036901526118ce01526000818161043f015281816108cb01526118690152600081816103b701528181610898015261189101526000818161039001528181610c890152610cfe01526000818161031d01528181610dd90152610e510152600081816102450152610b8d0152600081816102bc015281816108170152610bc6015260008181610cd60152610e2901526000818161027401526117940152600081816103f1015261175e0152600081816101e1015281816107930152818161106e015281816117ce01528181611a1b0152611a460152611fa16000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063a88dbb36116100c3578063cdbb0e691161007c578063cdbb0e69146103b2578063cf5aae19146103d9578063d401178e146103ec578063eb33bd3c14610413578063ef88dac11461043a578063f2fde38b1461046157600080fd5b8063a88dbb36146102de578063aa0effc5146102f1578063b235c94b14610318578063bd9a548b1461033f578063ca5ed14c14610364578063cc8825011461038b57600080fd5b806343ed99111161011557806343ed99111461021957806346eeb01a14610240578063715018a61461026757806385295c491461026f5780638da5cb5b146102a65780638dd79417146102b757600080fd5b80630738831b1461015d578063163f2c541461018d57806318f932c2146101b45780631d27050f146101c7578063210663e4146101dc578063329ea9b114610203575b600080fd5b600154610170906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101707f000000000000000000000000000000000000000000000000000000000000000081565b600354610170906001600160a01b031681565b6101da6101d5366004611aec565b610474565b005b6101707f000000000000000000000000000000000000000000000000000000000000000081565b61020b61050d565b604051908152602001610184565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101da610537565b6102967f000000000000000000000000000000000000000000000000000000000000000081565b6040519015158152602001610184565b6000546001600160a01b0316610170565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b600254610170906001600160a01b031681565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b61034761054b565b604080519315158452602084019290925290820152606001610184565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101da6103e7366004611b2e565b61062c565b6102967f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101da61046f366004611b2e565b610667565b61047c6106a7565b8063ffffffff166000036104a35760405163cad929df60e01b815260040160405180910390fd5b6003805463ffffffff838116600160a01b81810263ffffffff60a01b1985161790945560408051949093049091168084526020840191909152917f86139943149914833c057d2c24f3a3967cce8e6aba2eb12e422500d8a51ffc7b91015b60405180910390a15050565b600061051960006106d4565b610532906ec097ce7bc90715b34b9f1000000000611b61565b905090565b61053f6106a7565b6105496000610739565b565b6040516363737ac960e11b8152670de0b6b3a7640000600482018190526000918291829182906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c6e6f59290602401602060405180830381865afa1580156105c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e69190611b83565b90506105f0610789565b91965094509250816106028286611b9c565b61060c9190611b61565b9350816106198285611b9c565b6106239190611b61565b92505050909192565b6106346106a7565b6001600160a01b03811661065b57604051631b1689ab60e11b815260040160405180910390fd5b610664816109cf565b50565b61066f6106a7565b6001600160a01b03811661069e57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b61066481610739565b6000546001600160a01b031633146105495760405163118cdaa760e01b8152336004820152602401610695565b6000816000036106fd5760006106e8610b7b565b9350905080156106fb5750600092915050565b505b60025460035461071a916001600160a01b03908116911684610edb565b600254909150610733906001600160a01b0316826112cb565b92915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108139190611bb3565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615610895576000610850600061135f565b801596509050601260ff8316116108715761086c826012611bd6565b61087c565b61087c601283611bd6565b61088790600a611cd6565b6108919082611b9c565b9250505b817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158015906108f657507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15610960576000610905611852565b905060006109128261135f565b905060128460ff161161092f5761092a846012611bd6565b61093a565b61093a601285611bd6565b61094590600a611cd6565b61094f9082611b9c565b9250878061095b575081155b975050505b8215801561096c575080155b1561098a5760405163340d2cbf60e11b815260040160405180910390fd5b8260000361099d578094508093506109c7565b806000036109b0578294508293506109c7565b8083116109be5782816109c1565b80835b90955093505b505050909192565b6001600160a01b0381166109e05750565b6001546001600160a01b031615610a0a57604051634af85cf560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560408051632aa6a85160e21b8152905163aa9aa144916004808201926020929091908290030181865afa158015610a63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a879190611ce5565b600280546001600160a01b0319166001600160a01b0392909216918217905560408051632acada4d60e01b8152905160009291632acada4d91600480830192869291908290030181865afa158015610ae3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b0b9190810190611d72565b905080600081518110610b2057610b20611e6f565b60209081029190910181015151600380546001600160a01b0319166001600160a01b03928316179055600254604051911681527f02176273ef1668d41059376b23ac9b35710fdc7c4f5672098d43162c71b88cc29101610501565b600354604051630807aa9160e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03908116600483015280831660248301527f000000000000000000000000000000000000000000000000000000000000000081166044830152600160a01b90920463ffffffff16606482015260009182917f000000000000000000000000000000000000000000000000000000000000000090911690630807aa91906084016040805180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c729190611e85565b90925090508115610c87575060019160009150565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615610dd757604051630807aa9160e01b81526000600482018190526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248401527f00000000000000000000000000000000000000000000000000000000000000008116604484015260648301829052909182917f00000000000000000000000000000000000000000000000000000000000000001690630807aa91906084016040805180830381865afa158015610d77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9b9190611e85565b915091508115610db2575060019360009350915050565b80610dc584670de0b6b3a7640000611b9c565b610dcf9190611b61565b925050509091565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615610ed757600354604051630807aa9160e01b81526000600482018190526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248401527f000000000000000000000000000000000000000000000000000000000000000081166044840152600160a01b90930463ffffffff1660648301529182917f000000000000000000000000000000000000000000000000000000000000000090911690630807aa91906084016040805180830381865afa158015610d77573d6000803e3d6000fd5b9091565b60006001600160a01b038316610f78576000846001600160a01b0316632acada4d6040518163ffffffff1660e01b8152600401600060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f539190810190611d72565b905080600081518110610f6857610f68611e6f565b6020026020010151600001519350505b6000836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdc9190611bb3565b610fe790600a611cd6565b856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110499190611bb3565b61105490600a611cd6565b61105e9085611b9c565b6110689190611b61565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03161480156111115750856001600160a01b0316635ca8861f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110a9190611bb3565b60ff166001145b15611187576040516359339af360e11b8152600481018390526001600160a01b0387169063b26735e6906024015b602060405180830381865afa15801561115c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111809190611b83565b9050611239565b856001600160a01b0316636a5e26506040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e99190611bb3565b60ff16600103611220576040516303d1689d60e11b8152600481018390526001600160a01b038716906307a2d13a9060240161113f565b604051634f10a27f60e11b815260040160405180910390fd5b856001600160a01b031663bdc8d0606040518163ffffffff1660e01b8152600401602060405180830381865afa158015611277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129b9190611eb8565b6112a790612710611edc565b61ffff166112b782612710611b9c565b6112c19190611b61565b9695505050505050565b600080836001600160a01b031663bdc8d0606040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113309190611eb8565b905061271061134361ffff831685611b9c565b61134d9190611b61565b6113579084611ef6565b949350505050565b60008061136b836106d4565b9050600061137761194d565b604051630fa6707960e21b81526001600160a01b03828116600483015291925060009182917f000000000000000000000000000000000000000000000000000000000000000090911690633e99c1e4906024016040805180830381865afa1580156113e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140a9190611f25565b915091506000816001600160701b0316836001600160701b031661142e9190611b9c565b90506000846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114949190611ce5565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f59190611bb3565b61150090600a611cd6565b856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561153e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115629190611ce5565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561159f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c39190611bb3565b6115ce90600a611cd6565b6115d89190611b9c565b905060006115f9826115ea858a611b9c565b6115f49190611b61565b6119bb565b61160b90670de0b6b3a7640000611b9c565b90506000866001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561164d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116719190611b83565b90508060000361168b575060009998505050505050505050565b600081886001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f09190611bb3565b6116fb90600a611cd6565b611706856002611b9c565b6117109190611b9c565b61171a9190611b61565b90508060000361173d5760405163e9c8240960e01b815260040160405180910390fd5b61175a81722cd76fe086b93ce2f768a00b22a00000000000611b61565b99507f0000000000000000000000000000000000000000000000000000000000000000156117925761178b8a611a14565b9950611844565b7f000000000000000000000000000000000000000000000000000000000000000015611844576040516303d1689d60e11b8152600481018b90527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307a2d13a90602401602060405180830381865afa15801561181d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118419190611b83565b99505b505050505050505050919050565b604051630807aa9160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000811660248301526000604483018190526064830181905291829182917f000000000000000000000000000000000000000000000000000000000000000090911690630807aa91906084016040805180830381865afa158015611916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193a9190611e85565b9150915081156107335760009250505090565b600154604080516372f702f360e01b815290516000926001600160a01b0316916372f702f39160048083019260209291908290030181865afa158015611997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105329190611ce5565b60008060026119cb846001611f58565b6119d59190611b61565b90508291505b81811015611a0e579050806002816119f38186611b61565b6119fd9190611f58565b611a079190611b61565b90506119db565b50919050565b6000611a427f0000000000000000000000000000000000000000000000000000000000000000600084610edb565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ff140ca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac69190611eb8565b611ad290612710611edc565b61ffff16611ae282612710611b9c565b6107339190611b61565b600060208284031215611afe57600080fd5b813563ffffffff81168114611b1257600080fd5b9392505050565b6001600160a01b038116811461066457600080fd5b600060208284031215611b4057600080fd5b8135611b1281611b19565b634e487b7160e01b600052601160045260246000fd5b600082611b7e57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215611b9557600080fd5b5051919050565b808202811582820484141761073357610733611b4b565b600060208284031215611bc557600080fd5b815160ff81168114611b1257600080fd5b60ff828116828216039081111561073357610733611b4b565b6001815b6001841115611c2a57808504811115611c0e57611c0e611b4b565b6001841615611c1c57908102905b60019390931c928002611bf3565b935093915050565b600082611c4157506001610733565b81611c4e57506000610733565b8160018114611c645760028114611c6e57611c8a565b6001915050610733565b60ff841115611c7f57611c7f611b4b565b50506001821b610733565b5060208310610133831016604e8410600b8410161715611cad575081810a610733565b611cba6000198484611bef565b8060001904821115611cce57611cce611b4b565b029392505050565b6000611b1260ff841683611c32565b600060208284031215611cf757600080fd5b8151611b1281611b19565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715611d3b57611d3b611d02565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611d6a57611d6a611d02565b604052919050565b600060208284031215611d8457600080fd5b815167ffffffffffffffff811115611d9b57600080fd5b8201601f81018413611dac57600080fd5b805167ffffffffffffffff811115611dc657611dc6611d02565b611dd560208260051b01611d41565b80828252602082019150602060a08402850101925086831115611df757600080fd5b6020840193505b828410156112c15760a08488031215611e1657600080fd5b611e1e611d18565b8451611e2981611b19565b815260208581015190820152604080860151908201526060850151611e4d81611b19565b606082015260808581015190820152825260a090930192602090910190611dfe565b634e487b7160e01b600052603260045260246000fd5b60008060408385031215611e9857600080fd5b82518015158114611ea857600080fd5b6020939093015192949293505050565b600060208284031215611eca57600080fd5b815161ffff81168114611b1257600080fd5b61ffff828116828216039081111561073357610733611b4b565b8181038181111561073357610733611b4b565b80516001600160701b0381168114611f2057600080fd5b919050565b60008060408385031215611f3857600080fd5b611f4183611f09565b9150611f4f60208401611f09565b90509250929050565b8082018082111561073357610733611b4b56fea2646970667358221220536fedd0b2727cdaed7826318acbb5e61a1ebb18e77a623c63a82effae16796464736f6c634300081c0033a2646970667358221220d4fb90d407594481977da921d721c1f8907f1996885e11675ffbb5b06d2c5c3e64736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.