Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
PublicVault
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {ERC20} from "solmate/tokens/ERC20.sol"; import {ERC4626} from "solmate/mixins/ERC4626.sol"; import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol"; import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol"; import {SafeCastLib} from "gpl/utils/SafeCastLib.sol"; import {IERC165} from "core/interfaces/IERC165.sol"; import {ERC4626Cloned} from "gpl/ERC4626-Cloned.sol"; import {IERC4626} from "core/interfaces/IERC4626.sol"; import {IERC20} from "core/interfaces/IERC20.sol"; import {IERC20Metadata} from "core/interfaces/IERC20Metadata.sol"; import {ERC20Cloned} from "gpl/ERC20-Cloned.sol"; import { Create2ClonesWithImmutableArgs } from "create2-clones-with-immutable-args/Create2ClonesWithImmutableArgs.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {ILienToken} from "core/interfaces/ILienToken.sol"; import {VaultImplementation} from "core/VaultImplementation.sol"; import {WithdrawProxy} from "core/WithdrawProxy.sol"; import {IWithdrawProxy} from "core/interfaces/IWithdrawProxy.sol"; import {Math} from "core/utils/Math.sol"; import {IPublicVault} from "core/interfaces/IPublicVault.sol"; import {IAstariaVaultBase} from "core/interfaces/IAstariaVaultBase.sol"; import {AstariaVaultBase} from "core/AstariaVaultBase.sol"; import {IERC721Receiver} from "core/interfaces/IERC721Receiver.sol"; /* * @title PublicVault * @author androolloyd * @notice */ contract PublicVault is VaultImplementation, IPublicVault, ERC4626Cloned { using FixedPointMathLib for uint256; using SafeTransferLib for ERC20; using SafeCastLib for uint256; uint256 private constant PUBLIC_VAULT_SLOT = uint256(keccak256("xyz.astaria.PublicVault.storage.location")) - 1; function asset() public pure virtual override(IAstariaVaultBase, AstariaVaultBase, ERC4626Cloned) returns (address) { return super.asset(); } function decimals() public pure virtual override(IERC20Metadata) returns (uint8) { return 18; } function name() public view virtual override(IERC20Metadata, VaultImplementation) returns (string memory) { return string(abi.encodePacked("AST-Vault-", ERC20(asset()).symbol())); } function symbol() public view virtual override(IERC20Metadata, VaultImplementation) returns (string memory) { return string(abi.encodePacked("AST-V-", ERC20(asset()).symbol())); } function minDepositAmount() public view virtual override(ERC4626Cloned) returns (uint256) { if (ERC20(asset()).decimals() < 4) { return 10 ** (ERC20(asset()).decimals() - 1); } else if (ERC20(asset()).decimals() < 8) { return 10 ** (ERC20(asset()).decimals() - 2); } else { return 10 ** (ERC20(asset()).decimals() - 6); } } /** * @notice Signal a withdrawal of funds (redeeming for underlying asset) in the next epoch. * @param shares The number of VaultToken shares to redeem. * @param receiver The receiver of the WithdrawTokens (and eventual underlying asset) * @param owner The owner of the VaultTokens. * @return assets The amount of the underlying asset redeemed. */ function redeem( uint256 shares, address receiver, address owner ) public virtual override(ERC4626Cloned) returns (uint256 assets) { VaultData storage s = _loadStorageSlot(); assets = _redeemFutureEpoch(s, shares, receiver, owner, s.currentEpoch); } function withdraw( uint256 assets, address receiver, address owner ) public virtual override(ERC4626Cloned) returns (uint256 shares) { shares = previewWithdraw(assets); VaultData storage s = _loadStorageSlot(); _redeemFutureEpoch(s, shares, receiver, owner, s.currentEpoch); } /** * @notice Signal a withdrawal of funds (redeeming for underlying asset) in an arbitrary future epoch. * @param shares The number of VaultToken shares to redeem. * @param receiver The receiver of the WithdrawTokens (and eventual underlying asset) * @param owner The owner of the VaultTokens. * @param epoch The epoch to withdraw for. * @return assets The amount of the underlying asset redeemed. */ function redeemFutureEpoch( uint256 shares, address receiver, address owner, uint64 epoch ) public virtual returns (uint256 assets) { return _redeemFutureEpoch(_loadStorageSlot(), shares, receiver, owner, epoch); } function _redeemFutureEpoch( VaultData storage s, uint256 shares, address receiver, address owner, uint64 epoch ) internal virtual returns (uint256 assets) { // check to ensure that the requested epoch is not in the past ERC20Data storage es = _loadERC20Slot(); if (msg.sender != owner) { uint256 allowed = es.allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) { es.allowance[owner][msg.sender] = allowed - shares; } } if (epoch < s.currentEpoch) { revert InvalidVaultState(InvalidVaultStates.EPOCH_TOO_LOW); } require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS"); // check for rounding error since we round down in previewRedeem. if (assets < minDepositAmount()) { revert InvalidRedeemSize(); } //this will underflow if not enough balance es.balanceOf[owner] -= shares; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { es.balanceOf[address(this)] += shares; } emit Transfer(owner, address(this), shares); // Deploy WithdrawProxy if no WithdrawProxy exists for the specified epoch _deployWithdrawProxyIfNotDeployed(s, epoch); emit Withdraw(msg.sender, receiver, owner, assets, shares); // WithdrawProxy shares are minted 1:1 with PublicVault shares WithdrawProxy(s.epochData[epoch].withdrawProxy).mint(shares, receiver); } function getWithdrawProxy(uint64 epoch) public view returns (IWithdrawProxy) { return IWithdrawProxy(_loadStorageSlot().epochData[epoch].withdrawProxy); } /** * @notice * return the current epoch */ function getCurrentEpoch() public view returns (uint64) { return _loadStorageSlot().currentEpoch; } /** * @notice * return the current slope */ function getSlope() public view returns (uint256) { return uint256(_loadStorageSlot().slope); } /** * @notice * return the withdraw reserve */ function getWithdrawReserve() public view returns (uint256) { return uint256(_loadStorageSlot().withdrawReserve); } function getLiquidationWithdrawRatio() public view returns (uint256) { return uint256(_loadStorageSlot().liquidationWithdrawRatio); } function getYIntercept() public view returns (uint256) { return uint256(_loadStorageSlot().yIntercept); } function _deployWithdrawProxyIfNotDeployed( VaultData storage s, uint64 epoch ) internal { if (s.epochData[epoch].withdrawProxy == address(0)) { s.epochData[epoch].withdrawProxy = Create2ClonesWithImmutableArgs.clone( IAstariaRouter(ROUTER()).BEACON_PROXY_IMPLEMENTATION(), abi.encodePacked( address(ROUTER()), // router is the beacon uint8(IAstariaRouter.ImplementationType.WithdrawProxy), asset(), // token address(this), // vault epoch + 1 // claimable epoch ), keccak256(abi.encodePacked(address(this), epoch)) ); emit WithdrawProxyDeployed(epoch, s.epochData[epoch].withdrawProxy); } } function mint( uint256 shares, address receiver ) public override(ERC4626Cloned) whenNotPaused returns (uint256) { VIData storage s = _loadVISlot(); if (s.allowListEnabled) { require(s.allowList[receiver]); } return super.mint(shares, receiver); } /** * @notice Deposit funds into the PublicVault. * @param amount The amount of funds to deposit. * @param receiver The receiver of the resulting VaultToken shares. */ function deposit( uint256 amount, address receiver ) public override(ERC4626Cloned) whenNotPaused returns (uint256) { VIData storage s = _loadVISlot(); if (s.allowListEnabled) { require(s.allowList[receiver]); } return super.deposit(amount, receiver); } function getPublicVaultState() public view returns (uint256, uint256, uint40, uint64, uint256, uint256, uint256) { VaultData storage s = _loadStorageSlot(); return ( s.yIntercept, s.slope, s.last, s.currentEpoch, s.withdrawReserve, s.liquidationWithdrawRatio, s.balance ); } function getEpochData(uint64 epoch) public view returns (uint256, address) { VaultData storage s = _loadStorageSlot(); return ( s.epochData[epoch].liensOpenForEpoch, s.epochData[epoch].withdrawProxy ); } function getVirtualBalance() public view returns (uint256) { VaultData storage s = _loadStorageSlot(); return s.balance; } /** * @notice Retrieve the domain separator. * @return The domain separator. */ function computeDomainSeparator() internal view override returns (bytes32) { return super.domainSeparator(); } /** * @notice Rotate epoch boundary. This must be called before the next epoch can begin. */ function processEpoch() public { // check to make sure epoch is over if (timeToEpochEnd() > 0) { revert InvalidVaultState(InvalidVaultStates.EPOCH_NOT_OVER); } VaultData storage s = _loadStorageSlot(); if (s.withdrawReserve > 0) { revert InvalidVaultState(InvalidVaultStates.WITHDRAW_RESERVE_NOT_ZERO); } WithdrawProxy currentWithdrawProxy = WithdrawProxy( s.epochData[s.currentEpoch].withdrawProxy ); // split funds from previous WithdrawProxy with PublicVault if hasn't been already if (s.currentEpoch != 0) { WithdrawProxy previousWithdrawProxy = WithdrawProxy( s.epochData[s.currentEpoch - 1].withdrawProxy ); if ( address(previousWithdrawProxy) != address(0) && previousWithdrawProxy.getFinalAuctionEnd() != 0 ) { previousWithdrawProxy.claim(); } } if (s.epochData[s.currentEpoch].liensOpenForEpoch > 0) { revert InvalidVaultState( InvalidVaultStates.LIENS_OPEN_FOR_EPOCH_NOT_ZERO ); } // reset liquidationWithdrawRatio to prepare for re calcualtion s.liquidationWithdrawRatio = 0; // check if there are LPs withdrawing this epoch if ((address(currentWithdrawProxy) != address(0))) { uint256 proxySupply = currentWithdrawProxy.totalSupply(); s.liquidationWithdrawRatio = totalSupply() == 0 ? 0 : proxySupply.mulDivDown(1e18, totalSupply()); currentWithdrawProxy.setWithdrawRatio(s.liquidationWithdrawRatio); uint256 expected = currentWithdrawProxy.getExpected(); if (totalAssets() > expected) { s.withdrawReserve = (totalAssets() - expected).mulWadDown( s.liquidationWithdrawRatio ); } else { s.withdrawReserve = 0; } _setYIntercept( s, totalAssets().mulDivDown(1e18 - s.liquidationWithdrawRatio, 1e18) ); s.last = block.timestamp.safeCastTo40(); // burn the tokens of the LPs withdrawing _burn(address(this), proxySupply); } emit ProcessEpoch(msg.sender, s.currentEpoch); // increment epoch unchecked { s.currentEpoch++; } } function supportsInterface( bytes4 interfaceId ) public pure override(IERC165) returns (bool) { return interfaceId == type(IPublicVault).interfaceId || interfaceId == type(ERC4626Cloned).interfaceId || interfaceId == type(ERC4626).interfaceId || interfaceId == type(ERC20).interfaceId || interfaceId == type(IERC165).interfaceId; } /** * @notice Transfers funds from the PublicVault to the WithdrawProxy. */ function transferWithdrawReserve() public { VaultData storage s = _loadStorageSlot(); if (s.currentEpoch == uint64(0)) { return; } address currentWithdrawProxy = s .epochData[s.currentEpoch - 1] .withdrawProxy; // prevents transfer to a non-existent WithdrawProxy // withdrawProxies are indexed by the epoch where they're deployed if (currentWithdrawProxy != address(0)) { uint256 withdrawBalance = ERC20(asset()).balanceOf(address(this)); // Note: the else case is where 100% is being withdrawn to the withdrawal proxy and 100% of assets are being liquidated // the if case is less than 100% being withdrawn to the withdrawal proxy and less than 100% of assets are being liquidated // in both of these scenarios we need to check for a withdrawal reserve as some assets that need to be settled for epoch rollover // https://github.com/code-423n4/2023-01-astaria-findings/issues/157 // prevent transfer of more assets then are available if (s.withdrawReserve <= withdrawBalance) { withdrawBalance = s.withdrawReserve; s.withdrawReserve = 0; } else { unchecked { s.withdrawReserve -= withdrawBalance; } } if (withdrawBalance > 0) { ERC20(asset()).safeTransfer(currentWithdrawProxy, withdrawBalance); s.balance -= withdrawBalance; WithdrawProxy(currentWithdrawProxy).increaseWithdrawReserveReceived( withdrawBalance ); emit WithdrawReserveTransferred(withdrawBalance); } } address withdrawProxy = s.epochData[s.currentEpoch].withdrawProxy; if ( s.withdrawReserve > 0 && // only happens if previous withdrawProxy exists timeToEpochEnd() == 0 && withdrawProxy != address(0) ) { uint256 drainBalance = WithdrawProxy(withdrawProxy).drain( s.withdrawReserve, currentWithdrawProxy ); unchecked { s.withdrawReserve -= drainBalance; } WithdrawProxy(currentWithdrawProxy).increaseWithdrawReserveReceived( drainBalance ); } } function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external virtual override returns (bytes4) { if ( operator == address(ROUTER()) && msg.sender == address(ROUTER().LIEN_TOKEN()) ) { ( uint256 amount, uint40 lienEnd, uint256 lienSlope, address feeTo, uint256 feeRake ) = abi.decode(data, (uint256, uint40, uint256, address, uint256)); VaultData storage s = _loadStorageSlot(); if (amount > s.balance) { revert InvalidVaultState( InvalidVaultStates.LOAN_GREATER_THAN_VIRTUAL_BALANCE ); } if (s.balance - amount < s.withdrawReserve) { revert InvalidVaultState( InvalidVaultStates.WITHDRAW_RESERVE_UNDER_COLLATERALIZED ); } s.balance -= amount; _addLien(tokenId, lienSlope, lienEnd); _issuePayout(amount, feeTo, feeRake); } return IERC721Receiver.onERC721Received.selector; } function _loadStorageSlot() internal pure returns (VaultData storage s) { uint256 slot = PUBLIC_VAULT_SLOT; assembly { s.slot := slot } } function accrue() public returns (uint256) { return _accrue(_loadStorageSlot()); } function _accrue(VaultData storage s) internal returns (uint256) { unchecked { s.yIntercept = (_totalAssets(s)); s.last = block.timestamp.safeCastTo40(); } emit YInterceptChanged(s.yIntercept); return s.yIntercept; } /** * @notice Computes the implied value of this PublicVault. This includes interest payments that have not yet been made. * @return The implied value for this PublicVault. */ function totalAssets() public view virtual override(ERC4626Cloned) returns (uint256) { VaultData storage s = _loadStorageSlot(); return _totalAssets(s); } function _totalAssets(VaultData storage s) internal view returns (uint256) { uint256 delta_t = block.timestamp - s.last; return uint256(s.slope).mulDivDown(delta_t, 1) + uint256(s.yIntercept); } function totalSupply() public view virtual override(IERC20, ERC20Cloned) returns (uint256) { return _loadERC20Slot()._totalSupply; } /** * @notice Hook to update the slope and yIntercept of the PublicVault on payment. * The rate for the LienToken is subtracted from the total slope of the PublicVault, and recalculated in afterPayment(). * @param params The params to adjust things */ function updateVault(UpdateVaultParams calldata params) external { _onlyAuth(); VaultData storage s = _loadStorageSlot(); _accrue(s); s.balance += params.amount; //we are a payment if (params.isRepayment) { if (params.decreaseInSlope > 0) { uint256 newSlope = s.slope - params.decreaseInSlope; _setSlope(s, newSlope); } _decreaseEpochLienCount(s, getLienEpoch(params.lienEnd)); } else if (!params.isRepayment && params.decreaseInYIntercept > 0) { // we are a liquidation and not a withdraw proxy _setYIntercept(s, s.yIntercept - params.decreaseInYIntercept); } _handleStrategistInterestReward(s, params.interestPaid); } function skim() external { VaultData storage s = _loadStorageSlot(); uint256 skimAmount = ERC20(asset()).balanceOf(address(this)) - s.balance; if (skimAmount > 0) { s.balance += skimAmount; _setYIntercept(s, s.yIntercept + skimAmount); } } function _setSlope(VaultData storage s, uint256 newSlope) internal { s.slope = newSlope; emit SlopeUpdated(newSlope); } function _decreaseEpochLienCount(VaultData storage s, uint64 epoch) internal { s.epochData[epoch].liensOpenForEpoch--; emit LiensOpenForEpochRemaining( epoch, s.epochData[epoch].liensOpenForEpoch ); } /** @notice * helper to return the LienEpoch for a given end date * @param end time to compute the end for */ function getLienEpoch(uint64 end) public pure returns (uint64) { return uint256(Math.ceilDiv(end - uint64(START()), EPOCH_LENGTH()) - 1) .safeCastTo64(); } function getEpochEnd(uint256 epoch) public pure returns (uint64) { return uint256(START() + (epoch + 1) * EPOCH_LENGTH()).safeCastTo64(); } function _increaseOpenLiens(VaultData storage s, uint64 epoch) internal { unchecked { s.epochData[epoch].liensOpenForEpoch++; } emit LiensOpenForEpochRemaining( epoch, s.epochData[epoch].liensOpenForEpoch ); } /** * @notice After-deposit hook to update the yIntercept of the PublicVault to reflect a capital contribution. * @param assets The amount of assets deposited to the PublicVault. * @param shares The resulting amount of VaultToken shares that were issued. */ function afterDeposit( uint256 assets, uint256 shares ) internal virtual override { VaultData storage s = _loadStorageSlot(); unchecked { s.yIntercept += assets; s.balance += assets; } VIData storage v = _loadVISlot(); if (v.depositCap != 0 && totalAssets() >= v.depositCap) { revert InvalidVaultState(InvalidVaultStates.DEPOSIT_CAP_EXCEEDED); } emit YInterceptChanged(s.yIntercept); } /** * @dev Handles the dilutive fees (on lien repayments) for strategists in VaultTokens. * @param interestPaid The amount that was paid. */ function _handleStrategistInterestReward( VaultData storage s, uint256 interestPaid ) internal virtual { if (VAULT_FEE() != uint256(0) && interestPaid > 0) { uint256 fee = interestPaid.mulWadDown(VAULT_FEE()); uint256 feeInShares = fee.mulDivDown(totalSupply(), totalAssets() - fee); _mint(owner(), feeInShares); } } function stopLien( uint256 auctionWindow, uint256 lienSlope, uint64 lienEnd, uint256 tokenId, uint256 owed ) public { _onlyLienToken(); VaultData storage s = _loadStorageSlot(); _accrue(s); unchecked { _setSlope(s, s.slope - lienSlope); } uint64 lienEpoch = getLienEpoch(lienEnd); _decreaseEpochLienCount(s, lienEpoch); uint256 timeToEnd = timeToEpochEnd(lienEpoch); if (timeToEnd < auctionWindow) { _deployWithdrawProxyIfNotDeployed(s, lienEpoch); address withdrawProxyIfNearBoundary = s .epochData[lienEpoch] .withdrawProxy; ROUTER().LIEN_TOKEN().safeTransferFrom( address(this), withdrawProxyIfNearBoundary, tokenId, abi.encode(owed, auctionWindow) ); } } function _addLien( uint256 tokenId, uint256 lienSlope, uint40 lienEnd ) internal { VaultData storage s = _loadStorageSlot(); _accrue(s); uint256 newSlope = s.slope + lienSlope; _setSlope(s, newSlope); //checks to make sure the current epoch isn't over if (timeToEpochEnd() == 0) { revert InvalidVaultState(InvalidVaultStates.EPOCH_ENDED); } uint64 epoch = getLienEpoch(lienEnd); _increaseOpenLiens(s, epoch); emit LienOpen(tokenId, epoch); } function _onlyLienToken() internal view { require(msg.sender == address(ROUTER().LIEN_TOKEN())); } function _onlyAuth() internal view { VaultData storage s = _loadStorageSlot(); uint64 currentEpoch = s.currentEpoch; require( (currentEpoch != 0 && msg.sender == s.epochData[currentEpoch - 1].withdrawProxy) || msg.sender == address(ROUTER().LIEN_TOKEN()) ); } function _setYIntercept(VaultData storage s, uint256 newYIntercept) internal { s.yIntercept = newYIntercept; emit YInterceptChanged(s.yIntercept); } /** * @return Seconds until the current epoch ends. */ function timeToEpochEnd() public view returns (uint256) { return timeToEpochEnd(_loadStorageSlot().currentEpoch); } function epochEndTimestamp(uint256 epoch) public pure returns (uint256) { return START() + ((epoch + 1) * EPOCH_LENGTH()); } function timeToEpochEnd(uint256 epoch) public view returns (uint256) { uint256 epochEnd = epochEndTimestamp(epoch); if (block.timestamp >= epochEnd) { return uint256(0); } return epochEnd - block.timestamp; } function timeToSecondEpochEnd() public view returns (uint256) { return _timeToSecondEndIfPublic(); } function _timeToSecondEndIfPublic() internal view returns (uint256 timeToSecondEpochEnd) { VaultData storage s = _loadStorageSlot(); return timeToEpochEnd(s.currentEpoch + 1); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol"; /// @notice Minimal ERC4626 tokenized Vault implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol) abstract contract ERC4626 is ERC20 { using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /*////////////////////////////////////////////////////////////// IMMUTABLES //////////////////////////////////////////////////////////////*/ ERC20 public immutable asset; constructor( ERC20 _asset, string memory _name, string memory _symbol ) ERC20(_name, _symbol, _asset.decimals()) { asset = _asset; } /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LOGIC //////////////////////////////////////////////////////////////*/ function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) { // Check for rounding error since we round down in previewDeposit. require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES"); // Need to transfer before minting or ERC777s could reenter. asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) { assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up. // Need to transfer before minting or ERC777s could reenter. asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } function withdraw( uint256 assets, address receiver, address owner ) public virtual returns (uint256 shares) { shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up. if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); asset.safeTransfer(receiver, assets); } function redeem( uint256 shares, address receiver, address owner ) public virtual returns (uint256 assets) { if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } // Check for rounding error since we round down in previewRedeem. require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS"); beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); asset.safeTransfer(receiver, assets); } /*////////////////////////////////////////////////////////////// ACCOUNTING LOGIC //////////////////////////////////////////////////////////////*/ function totalAssets() public view virtual returns (uint256); function convertToShares(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets()); } function convertToAssets(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply); } function previewDeposit(uint256 assets) public view virtual returns (uint256) { return convertToShares(assets); } function previewMint(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply); } function previewWithdraw(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets()); } function previewRedeem(uint256 shares) public view virtual returns (uint256) { return convertToAssets(shares); } /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LIMIT LOGIC //////////////////////////////////////////////////////////////*/ function maxDeposit(address) public view virtual returns (uint256) { return type(uint256).max; } function maxMint(address) public view virtual returns (uint256) { return type(uint256).max; } function maxWithdraw(address owner) public view virtual returns (uint256) { return convertToAssets(balanceOf[owner]); } function maxRedeem(address owner) public view virtual returns (uint256) { return balanceOf[owner]; } /*////////////////////////////////////////////////////////////// INTERNAL HOOKS LOGIC //////////////////////////////////////////////////////////////*/ function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {} function afterDeposit(uint256 assets, uint256 shares) internal virtual {} }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Arithmetic library with operations for fixed-point numbers. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) /// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ uint256 internal constant MAX_UINT256 = 2**256 - 1; uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } /*////////////////////////////////////////////////////////////// LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // Divide x * y by the denominator. z := div(mul(x, y), denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // If x * y modulo the denominator is strictly greater than 0, // 1 is added to round up the division of x * y by the denominator. z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator)) } } function rpow( uint256 x, uint256 n, uint256 scalar ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { switch x case 0 { switch n case 0 { // 0 ** 0 = 1 z := scalar } default { // 0 ** n = 0 z := 0 } } default { switch mod(n, 2) case 0 { // If n is even, store scalar in z for now. z := scalar } default { // If n is odd, store x in z for now. z := x } // Shifting right by 1 is like dividing by 2. let half := shr(1, scalar) for { // Shift n right by 1 before looping to halve it. n := shr(1, n) } n { // Shift n right by 1 each iteration to halve it. n := shr(1, n) } { // Revert immediately if x ** 2 would overflow. // Equivalent to iszero(eq(div(xx, x), x)) here. if shr(128, x) { revert(0, 0) } // Store x squared. let xx := mul(x, x) // Round to the nearest number. let xxRound := add(xx, half) // Revert if xx + half overflowed. if lt(xxRound, xx) { revert(0, 0) } // Set x to scaled xxRound. x := div(xxRound, scalar) // If n is even: if mod(n, 2) { // Compute z * x. let zx := mul(z, x) // If z * x overflowed: if iszero(eq(div(zx, x), z)) { // Revert if x is non-zero. if iszero(iszero(x)) { revert(0, 0) } } // Round to the nearest number. let zxRound := add(zx, half) // Revert if zx + half overflowed. if lt(zxRound, zx) { revert(0, 0) } // Return properly scaled zxRound. z := div(zxRound, scalar) } } } } } /*////////////////////////////////////////////////////////////// GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. // We check y >= 2^(k + 8) but shift right by k bits // each branch to ensure that if x >= 256, then y >= 256. if iszero(lt(y, 0x10000000000000000000000000000000000)) { y := shr(128, y) z := shl(64, z) } if iszero(lt(y, 0x1000000000000000000)) { y := shr(64, y) z := shl(32, z) } if iszero(lt(y, 0x10000000000)) { y := shr(32, y) z := shl(16, z) } if iszero(lt(y, 0x1000000)) { y := shr(16, y) z := shl(8, z) } // Goal was to get z*z*y within a small factor of x. More iterations could // get y in a tighter range. Currently, we will have y in [256, 256*2^16). // We ensured y >= 256 so that the relative difference between y and y+1 is small. // That's not possible if x < 256 but we can just verify those cases exhaustively. // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. // There is no overflow risk here since y < 2^136 after the first branch above. z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) // If x+1 is a perfect square, the Babylonian method cycles between // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. // If you don't care whether the floor or ceil square root is returned, you can remove this statement. z := sub(z, lt(div(x, z), z)) } } function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Mod x by y. Note this will return // 0 instead of reverting if y is zero. z := mod(x, y) } } function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Divide x by y. Note this will return // 0 instead of reverting if y is zero. r := div(x, y) } } function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Add 1 to x * y if x % y > 0. Note this will // return 0 instead of reverting if y is zero. z := add(gt(mod(x, y), 0), div(x, y)) } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Safe unsigned integer casting library that reverts on overflow. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeCastLib.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol) library SafeCastLib { function safeCastTo248(uint256 x) internal pure returns (uint248 y) { require(x < 1 << 248); y = uint248(x); } function safeCastTo240(uint256 x) internal pure returns (uint240 y) { require(x < 1 << 240); y = uint240(x); } function safeCastTo224(uint256 x) internal pure returns (uint224 y) { require(x < 1 << 224); y = uint224(x); } function safeCastTo216(uint256 x) internal pure returns (uint216 y) { require(x < 1 << 216); y = uint216(x); } function safeCastTo208(uint256 x) internal pure returns (uint208 y) { require(x < 1 << 208); y = uint208(x); } function safeCastTo200(uint256 x) internal pure returns (uint200 y) { require(x < 1 << 200); y = uint200(x); } function safeCastTo192(uint256 x) internal pure returns (uint192 y) { require(x < 1 << 192); y = uint192(x); } function safeCastTo176(uint256 x) internal pure returns (uint176 y) { require(x < 1 << 176); y = uint176(x); } function safeCastTo160(uint256 x) internal pure returns (uint160 y) { require(x < 1 << 160); y = uint160(x); } function safeCastTo128(uint256 x) internal pure returns (uint128 y) { require(x < 1 << 128); y = uint128(x); } function safeCastTo96(uint256 x) internal pure returns (uint96 y) { require(x < 1 << 96); y = uint96(x); } function safeCastTo88(uint256 x) internal pure returns (uint88 y) { require(x < 1 << 88); y = uint88(x); } function safeCastTo64(uint256 x) internal pure returns (uint64 y) { require(x < 1 << 64); y = uint64(x); } function safeCastTo32(uint256 x) internal pure returns (uint32 y) { require(x < 1 << 32); y = uint32(x); } function safeCastTo40(uint256 x) internal pure returns (uint40 y) { require(x < 1 << 40); y = uint40(x); } function safeCastTo48(uint256 x) internal pure returns (uint48 y) { require(x < 1 << 48); y = uint48(x); } function safeCastTo24(uint256 x) internal pure returns (uint24 y) { require(x < 1 << 24); y = uint24(x); } function safeCastTo16(uint256 x) internal pure returns (uint16 y) { require(x < 1 << 16); y = uint16(x); } function safeCastTo8(uint256 x) internal pure returns (uint8 y) { require(x < 1 << 8); y = uint8(x); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity =0.8.17; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.16; import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol"; import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol"; import {Clone} from "create2-clones-with-immutable-args/Clone.sol"; import {ERC20} from "solmate/tokens/ERC20.sol"; import {ERC20Cloned} from "gpl/ERC20-Cloned.sol"; import {IERC4626} from "core/interfaces/IERC4626.sol"; abstract contract ERC4626Cloned is IERC4626, ERC20Cloned { using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; function minDepositAmount() public view virtual returns (uint256); function asset() public view virtual returns (address); function deposit( uint256 assets, address receiver ) public virtual returns (uint256 shares) { // Check for rounding error since we round down in previewDeposit. require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES"); require(shares > minDepositAmount(), "VALUE_TOO_SMALL"); // Need to transfer before minting or ERC777s could reenter. ERC20(asset()).safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } function mint( uint256 shares, address receiver ) public virtual returns (uint256 assets) { assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up. require(assets > minDepositAmount(), "VALUE_TOO_SMALL"); // Need to transfer before minting or ERC777s could reenter. ERC20(asset()).safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } function withdraw( uint256 assets, address receiver, address owner ) public virtual returns (uint256 shares) { shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up. ERC20Data storage s = _loadERC20Slot(); if (msg.sender != owner) { uint256 allowed = s.allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) { s.allowance[owner][msg.sender] = allowed - shares; } } beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); ERC20(asset()).safeTransfer(receiver, assets); } function redeem( uint256 shares, address receiver, address owner ) public virtual returns (uint256 assets) { ERC20Data storage s = _loadERC20Slot(); if (msg.sender != owner) { uint256 allowed = s.allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) { s.allowance[owner][msg.sender] = allowed - shares; } } // Check for rounding error since we round down in previewRedeem. require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS"); beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); ERC20(asset()).safeTransfer(receiver, assets); } function totalAssets() public view virtual returns (uint256); function convertToShares( uint256 assets ) public view virtual returns (uint256) { uint256 supply = totalSupply(); // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets()); } function convertToAssets( uint256 shares ) public view virtual returns (uint256) { uint256 supply = totalSupply(); // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply); } function previewDeposit( uint256 assets ) public view virtual returns (uint256) { return convertToShares(assets); } function previewMint(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply(); // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? 10e18 : shares.mulDivUp(totalAssets(), supply); } function previewWithdraw( uint256 assets ) public view virtual returns (uint256) { uint256 supply = totalSupply(); // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? 10e18 : assets.mulDivUp(supply, totalAssets()); } function previewRedeem(uint256 shares) public view virtual returns (uint256) { return convertToAssets(shares); } function maxDeposit(address) public view virtual returns (uint256) { return type(uint256).max; } function maxMint(address) public view virtual returns (uint256) { return type(uint256).max; } function maxWithdraw(address owner) public view virtual returns (uint256) { ERC20Data storage s = _loadERC20Slot(); return convertToAssets(s.balanceOf[owner]); } function maxRedeem(address owner) public view virtual returns (uint256) { ERC20Data storage s = _loadERC20Slot(); return s.balanceOf[owner]; } function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {} function afterDeposit(uint256 assets, uint256 shares) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC4626.sol) pragma solidity =0.8.17; import {IERC20} from "core/interfaces/IERC20.sol"; import {IERC20Metadata} from "core/interfaces/IERC20Metadata.sol"; /** * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. * * _Available since v4.7._ */ 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: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity =0.8.17; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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 amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance( address owner, address spender ) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
pragma solidity =0.8.17; import {IERC20} from "core/interfaces/IERC20.sol"; 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.16; import {IERC20} from "core/interfaces/IERC20.sol"; import {IERC20Metadata} from "core/interfaces/IERC20Metadata.sol"; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20Cloned is IERC20Metadata { uint256 constant ERC20_SLOT = uint256(keccak256("xyz.astaria.ERC20.storage.location")) - 1; bytes32 private constant PERMIT_TYPEHASH = keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ); struct ERC20Data { uint256 _totalSupply; mapping(address => uint256) balanceOf; mapping(address => mapping(address => uint256)) allowance; mapping(address => uint256) nonces; } function _loadERC20Slot() internal pure returns (ERC20Data storage s) { uint256 slot = ERC20_SLOT; assembly { s.slot := slot } } function balanceOf(address account) external view returns (uint256) { return _loadERC20Slot().balanceOf[account]; } function approve(address spender, uint256 amount) public virtual returns (bool) { ERC20Data storage s = _loadERC20Slot(); s.allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { ERC20Data storage s = _loadERC20Slot(); s.balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { s.balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function allowance(address owner, address spender) external view returns (uint256) { ERC20Data storage s = _loadERC20Slot(); return s.allowance[owner][spender]; } function totalSupply() public view virtual returns (uint256) { ERC20Data storage s = _loadERC20Slot(); return s._totalSupply; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { ERC20Data storage s = _loadERC20Slot(); uint256 allowed = s.allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) { s.allowance[from][msg.sender] = allowed - amount; } s.balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { s.balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( PERMIT_TYPEHASH, owner, spender, value, _loadERC20Slot().nonces[owner]++, deadline ) ) ) ), v, r, s ); require( recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER" ); _loadERC20Slot().allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256( "EIP712Domain(string version,uint256 chainId,address verifyingContract)" ), keccak256("1"), block.chainid, address(this) ) ); } function _mint(address to, uint256 amount) internal virtual { ERC20Data storage s = _loadERC20Slot(); s._totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { s.balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { ERC20Data storage s = _loadERC20Slot(); s.balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { s._totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: BSD pragma solidity ^0.8.4; import { Create2AddressDeriver } from "create2-helpers/lib/Create2AddressDeriver.sol"; /// @title Create2ClonesWithImmutableArgs /// @author wighawag, zefram.eth, emo.eth /// @notice Enables creating clone contracts with immutable args to deterministic addresses library Create2ClonesWithImmutableArgs { error CreateFail(); /// @notice Creates a clone proxy of the implementation contract, with immutable args /// @dev data cannot exceed 65535 bytes, since 2 bytes are used to store the data length /// @param implementation The implementation contract to clone /// @param data Encoded immutable args /// @return instance The address of the created clone function clone(address implementation, bytes memory data, bytes32 salt) internal returns (address payable instance) { (uint256 ptr, uint256 creationSize) = _createBytecode(implementation, data); // solhint-disable-next-line no-inline-assembly assembly { instance := create2(0, ptr, creationSize, salt) } if (instance == address(0)) { revert CreateFail(); } } function deriveAddress(address deployer, address implementation, bytes memory data, bytes32 salt) internal pure returns (address) { (uint256 ptr, uint256 codeLength) = _createBytecode(implementation, data); bytes memory creationCode; // the clones library does not store length before the bytecode, so we need to do it ourselves // we'll cache the value at sub(ptr, 0x20) and restore it after uint256 cached; ///@solidity memory-safe-assembly assembly { creationCode := sub(ptr, 0x20) cached := mload(creationCode) mstore(creationCode, codeLength) } address derived = Create2AddressDeriver.deriveCreate2Address(deployer, salt, creationCode); // restore cached value ///@solidity memory-safe-assembly assembly { mstore(creationCode, cached) } return derived; } function _createBytecode(address implementation, bytes memory data) internal pure returns (uint256 ptr, uint256 creationSize) { // unrealistic for memory ptr or data length to exceed 256 bits unchecked { uint256 extraLength = data.length + 2; // +2 bytes for telling how much data there is appended to the call creationSize = 0x41 + extraLength; uint256 runSize = creationSize - 10; uint256 dataPtr; // solhint-disable-next-line no-inline-assembly assembly { ptr := mload(0x40) // ------------------------------------------------------------------------------------------------------------- // CREATION (10 bytes) // ------------------------------------------------------------------------------------------------------------- // 61 runtime | PUSH2 runtime (r) | r | – mstore(ptr, 0x6100000000000000000000000000000000000000000000000000000000000000) mstore(add(ptr, 0x01), shl(240, runSize)) // size of the contract running bytecode (16 bits) // creation size = 0a // 3d | RETURNDATASIZE | 0 r | – // 81 | DUP2 | r 0 r | – // 60 creation | PUSH1 creation (c) | c r 0 r | – // 3d | RETURNDATASIZE | 0 c r 0 r | – // 39 | CODECOPY | 0 r | [0-runSize): runtime code // f3 | RETURN | | [0-runSize): runtime code // ------------------------------------------------------------------------------------------------------------- // RUNTIME (55 bytes + extraLength) // ------------------------------------------------------------------------------------------------------------- // 3d | RETURNDATASIZE | 0 | – // 3d | RETURNDATASIZE | 0 0 | – // 3d | RETURNDATASIZE | 0 0 0 | – // 3d | RETURNDATASIZE | 0 0 0 0 | – // 36 | CALLDATASIZE | cds 0 0 0 0 | – // 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | – // 3d | RETURNDATASIZE | 0 0 cds 0 0 0 0 | – // 37 | CALLDATACOPY | 0 0 0 0 | [0, cds) = calldata // 61 | PUSH2 extra | extra 0 0 0 0 | [0, cds) = calldata mstore(add(ptr, 0x03), 0x3d81600a3d39f33d3d3d3d363d3d376100000000000000000000000000000000) mstore(add(ptr, 0x13), shl(240, extraLength)) // 60 0x37 | PUSH1 0x37 | 0x37 extra 0 0 0 0 | [0, cds) = calldata // 0x37 (55) is runtime size - data // 36 | CALLDATASIZE | cds 0x37 extra 0 0 0 0 | [0, cds) = calldata // 39 | CODECOPY | 0 0 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData // 36 | CALLDATASIZE | cds 0 0 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData // 61 extra | PUSH2 extra | extra cds 0 0 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData mstore(add(ptr, 0x15), 0x6037363936610000000000000000000000000000000000000000000000000000) mstore(add(ptr, 0x1b), shl(240, extraLength)) // 01 | ADD | cds+extra 0 0 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData // 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData // 73 addr | PUSH20 0x123… | addr 0 cds 0 0 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData mstore(add(ptr, 0x1d), 0x013d730000000000000000000000000000000000000000000000000000000000) mstore(add(ptr, 0x20), shl(0x60, implementation)) // 5a | GAS | gas addr 0 cds 0 0 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData // f4 | DELEGATECALL | success 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData // 3d | RETURNDATASIZE | rds success 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData // 3d | RETURNDATASIZE | rds rds success 0 0 | [0, cds) = calldata, [cds, cds+0x37) = extraData // 93 | SWAP4 | 0 rds success 0 rds | [0, cds) = calldata, [cds, cds+0x37) = extraData // 80 | DUP1 | 0 0 rds success 0 rds | [0, cds) = calldata, [cds, cds+0x37) = extraData // 3e | RETURNDATACOPY | success 0 rds | [0, rds) = return data (there might be some irrelevant leftovers in memory [rds, cds+0x37) when rds < cds+0x37) // 60 0x35 | PUSH1 0x35 | 0x35 sucess 0 rds | [0, rds) = return data // 57 | JUMPI | 0 rds | [0, rds) = return data // fd | REVERT | – | [0, rds) = return data // 5b | JUMPDEST | 0 rds | [0, rds) = return data // f3 | RETURN | – | [0, rds) = return data mstore(add(ptr, 0x34), 0x5af43d3d93803e603557fd5bf300000000000000000000000000000000000000) } // ------------------------------------------------------------------------------------------------------------- // APPENDED DATA (Accessible from extcodecopy) // (but also send as appended data to the delegatecall) // ------------------------------------------------------------------------------------------------------------- extraLength -= 2; uint256 counter = extraLength; uint256 copyPtr = ptr + 0x41; // solhint-disable-next-line no-inline-assembly assembly { dataPtr := add(data, 32) } for (; counter >= 32; counter -= 32) { // solhint-disable-next-line no-inline-assembly assembly { mstore(copyPtr, mload(dataPtr)) } copyPtr += 32; dataPtr += 32; } uint256 mask = ~(256 ** (32 - counter) - 1); // solhint-disable-next-line no-inline-assembly assembly { mstore(copyPtr, and(mload(dataPtr), mask)) } copyPtr += counter; // solhint-disable-next-line no-inline-assembly assembly { mstore(copyPtr, shl(240, extraLength)) } } return (ptr, creationSize); } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IERC721} from "core/interfaces/IERC721.sol"; import {ITransferProxy} from "core/interfaces/ITransferProxy.sol"; import {IERC4626} from "core/interfaces/IERC4626.sol"; import {ERC20} from "solmate/tokens/ERC20.sol"; import {ICollateralToken} from "core/interfaces/ICollateralToken.sol"; import {ILienToken} from "core/interfaces/ILienToken.sol"; import {IPausable} from "core/utils/Pausable.sol"; import {IBeacon} from "core/interfaces/IBeacon.sol"; // import {IERC4626RouterBase} from "gpl/interfaces/IERC4626RouterBase.sol"; import {OrderParameters} from "seaport-types/src/lib/ConsiderationStructs.sol"; interface IAstariaRouter is IPausable, IBeacon { enum FileType { FeeTo, LiquidationFee, ProtocolFee, MaxStrategistFee, MinEpochLength, MaxEpochLength, MinInterestRate, MaxInterestRate, MinLoanDuration, AuctionWindow, StrategyValidator, Implementation, CollateralToken, LienToken, TransferProxy } struct File { FileType what; bytes data; } event FileUpdated(FileType what, bytes data); struct RouterStorage { //slot 1 uint32 auctionWindow; uint32 liquidationFeeNumerator; uint32 liquidationFeeDenominator; uint32 maxEpochLength; uint32 minEpochLength; uint32 protocolFeeNumerator; uint32 protocolFeeDenominator; uint32 minLoanDuration; //slot 2 ICollateralToken COLLATERAL_TOKEN; //20 ILienToken LIEN_TOKEN; //20 ITransferProxy TRANSFER_PROXY; //20 address feeTo; //20 address BEACON_PROXY_IMPLEMENTATION; //20 uint256 maxInterestRate; //6 //slot 3 + address guardian; //20 address newGuardian; //20 mapping(uint8 => address) strategyValidators; mapping(uint8 => address) implementations; //A strategist can have many deployed vaults mapping(address => bool) vaults; uint256 maxStrategistFee; //4 address WETH; } enum ImplementationType { PrivateVault, PublicVault, WithdrawProxy } enum LienRequestType { DEACTIVATED, UNIQUE, COLLECTION, UNIV3_LIQUIDITY } struct StrategyDetailsParam { uint8 version; uint256 deadline; address payable vault; } struct MerkleData { bytes32 root; bytes32[] proof; } struct NewLienRequest { StrategyDetailsParam strategy; bytes nlrDetails; bytes32 root; bytes32[] proof; uint256 amount; uint8 v; bytes32 r; bytes32 s; } struct Commitment { address tokenContract; uint256 tokenId; NewLienRequest lienRequest; } function STRATEGY_TYPEHASH() external view returns (bytes32); function validateCommitment( IAstariaRouter.Commitment calldata commitment ) external returns (ILienToken.Lien memory lien); function getStrategyValidator( Commitment calldata ) external view returns (address); function newPublicVault( uint256 epochLength, address delegate, address underlying, uint256 vaultFee, bool allowListEnabled, address[] calldata allowList, uint256 depositCap ) external returns (address); function newVault( address delegate, address underlying ) external returns (address); function feeTo() external view returns (address); function WETH() external view returns (address); function commitToLien( Commitment memory commitments ) external returns (uint256, ILienToken.Stack memory); function LIEN_TOKEN() external view returns (ILienToken); function TRANSFER_PROXY() external view returns (ITransferProxy); function BEACON_PROXY_IMPLEMENTATION() external view returns (address); function COLLATERAL_TOKEN() external view returns (ICollateralToken); function getAuctionWindow() external view returns (uint256); function getProtocolFee(uint256) external view returns (uint256); function getLiquidatorFee(uint256) external view returns (uint256); function liquidate( ILienToken.Stack calldata stack ) external returns (OrderParameters memory); function canLiquidate(ILienToken.Stack calldata) external view returns (bool); function isValidVault(address vault) external view returns (bool); function fileBatch(File[] calldata files) external; function file(File calldata incoming) external; function setNewGuardian(address _guardian) external; function fileGuardian(File[] calldata file) external; function getImpl(uint8 implType) external view returns (address impl); event Liquidation(uint256 lienId, address liquidator); event NewVault( address strategist, address delegate, address vault, uint8 vaultType ); error InvalidFileData(); error InvalidEpochLength(uint256); error InvalidRefinanceRate(uint256); error InvalidRefinanceDuration(uint256); error InvalidVaultFee(); error InvalidVaultState(VaultState); error InvalidSenderForCollateral(address, uint256); error InvalidLienState(LienState); error InvalidCollateralState(CollateralStates); error InvalidCommitmentState(CommitmentState); error InvalidStrategy(uint16); error InvalidVault(address); error InvalidUnderlying(address); error InvalidSender(); error StrategyExpired(); error UnsupportedFile(); enum LienState { HEALTHY, AUCTION } enum CollateralStates { AUCTION, NO_DEPOSIT, NO_LIENS } enum CommitmentState { INVALID, INVALID_RATE, INVALID_AMOUNT, COLLATERAL_NO_DEPOSIT } enum VaultState { UNINITIALIZED, SHUTDOWN, CORRUPTED } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IERC721} from "core/interfaces/IERC721.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {ICollateralToken} from "core/interfaces/ICollateralToken.sol"; import {ITransferProxy} from "core/interfaces/ITransferProxy.sol"; interface ILienToken is IERC721 { enum FileType { NotSupported, CollateralToken, AstariaRouter, BuyoutFee, BuyoutFeeDurationCap, MinInterestBPS, MinDurationIncrease, MinLoanDuration } struct File { FileType what; bytes data; } event FileUpdated(FileType what, bytes data); struct LienStorage { IAstariaRouter ASTARIA_ROUTER; ICollateralToken COLLATERAL_TOKEN; mapping(uint256 => bytes32) collateralStateHash; mapping(uint256 => AuctionData) collateralLiquidator; } struct AuctionData { uint256 amountOwed; address liquidator; } struct Details { uint256 maxAmount; uint256 rate; //rate per second uint256 duration; uint256 maxPotentialDebt; uint256 liquidationInitialAsk; } struct Lien { uint8 collateralType; address token; //20 address payable vault; //20 uint256 collateralId; //32 //contractAddress + tokenId Details details; //32 * 5 } struct Point { uint256 amount; //11 uint40 last; //5 uint40 end; //5 } struct Stack { Lien lien; Point point; } struct LienActionEncumber { uint256 amount; address receiver; ILienToken.Lien lien; address feeTo; uint256 fee; } function calculateSlope( Stack calldata stack ) external pure returns (uint256 slope); function handleLiquidation( uint256 auctionWindow, Stack calldata stack, address liquidator ) external; function getOwed(Stack calldata stack) external view returns (uint256); function getOwed( Stack calldata stack, uint256 timestamp ) external view returns (uint256); function getInterest(Stack calldata stack) external returns (uint256); function getCollateralState( uint256 collateralId ) external view returns (bytes32); function createLien( LienActionEncumber calldata params ) external returns (uint256 lienId, Stack memory stack, uint256 owingAtEnd); function makePayment(Stack memory stack) external; function getAuctionLiquidator( uint256 collateralId ) external view returns (address liquidator); function getAuctionData( uint256 collateralId ) external view returns (AuctionData memory); function file(File calldata file) external; event NewLien(uint256 indexed collateralId, Stack stack); event Payment(uint256 indexed lienId, uint256 amount); error InvalidFileData(); error UnsupportedFile(); error InvalidTokenId(uint256 tokenId); error InvalidLoanState(); error InvalidSender(); enum InvalidLienStates { INVALID_LIEN_ID, INVALID_HASH, INVALID_LIQUIDATION_INITIAL_ASK, PUBLIC_VAULT_RECIPIENT, COLLATERAL_NOT_LIQUIDATED, COLLATERAL_LIQUIDATED, AMOUNT_ZERO, MIN_DURATION_NOT_MET } error InvalidLienState(InvalidLienStates); }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {ERC20} from "solmate/tokens/ERC20.sol"; import {ERC721, ERC721TokenReceiver} from "solmate/tokens/ERC721.sol"; import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol"; import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol"; import {CollateralLookup} from "core/libraries/CollateralLookup.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {LienToken} from "core/LienToken.sol"; import {ILienToken} from "core/interfaces/ILienToken.sol"; import {IPublicVault} from "core/interfaces/IPublicVault.sol"; import {AstariaVaultBase} from "core/AstariaVaultBase.sol"; import {IVaultImplementation} from "core/interfaces/IVaultImplementation.sol"; import {SafeCastLib} from "gpl/utils/SafeCastLib.sol"; /** * @title VaultImplementation * @notice A base implementation for the minimal features of an Astaria Vault. */ abstract contract VaultImplementation is AstariaVaultBase, ERC721TokenReceiver, IVaultImplementation { using SafeTransferLib for ERC20; using SafeCastLib for uint256; using CollateralLookup for address; using FixedPointMathLib for uint256; bytes32 constant EIP_DOMAIN = keccak256( "EIP712Domain(string version,uint256 chainId,address verifyingContract)" ); bytes32 constant VERSION = keccak256("0"); function name() external view virtual override returns (string memory); function symbol() external view virtual override returns (string memory); uint256 private constant VI_SLOT = uint256(keccak256("xyz.astaria.VaultImplementation.storage.location")) - 1; function getStrategistNonce() external view returns (uint256) { return _loadVISlot().strategistNonce; } function getState() external view virtual returns (uint256, address, address, bool, bool, uint256, bytes32) { VIData storage s = _loadVISlot(); return ( s.depositCap, s.delegate, owner(), s.allowListEnabled, s.isShutdown, s.strategistNonce, domainSeparator() ); } function getAllowList(address depositor) external view returns (bool) { VIData storage s = _loadVISlot(); if (!s.allowListEnabled) { return true; } return s.allowList[depositor]; } function incrementNonce() external { VIData storage s = _loadVISlot(); if (msg.sender != owner() && msg.sender != s.delegate) { revert InvalidRequest(InvalidRequestReason.NO_AUTHORITY); } s.strategistNonce += uint256(blockhash(block.number - 1) >> 0x80); emit NonceUpdated(s.strategistNonce); } /** * @notice modify the deposit cap for the vault * @param newCap The deposit cap. */ function modifyDepositCap(uint256 newCap) external { require(msg.sender == owner()); //owner is "strategist" _loadVISlot().depositCap = newCap; } function _loadVISlot() internal pure returns (VIData storage s) { uint256 slot = VI_SLOT; assembly { s.slot := slot } } /** * @notice modify the allowlist for the vault * @param depositor the depositor to modify * @param enabled the status of the depositor */ function modifyAllowList(address depositor, bool enabled) external virtual { require(msg.sender == owner()); //owner is "strategist" _loadVISlot().allowList[depositor] = enabled; emit AllowListUpdated(depositor, enabled); } /** * @notice disable the allowList for the vault */ function disableAllowList() external virtual { require(msg.sender == owner()); //owner is "strategist" _loadVISlot().allowListEnabled = false; emit AllowListEnabled(false); } /** * @notice enable the allowList for the vault */ function enableAllowList() external virtual { require(msg.sender == owner()); //owner is "strategist" _loadVISlot().allowListEnabled = true; emit AllowListEnabled(true); } modifier whenNotPaused() { if (ROUTER().paused()) { revert InvalidRequest(InvalidRequestReason.PAUSED); } if (_loadVISlot().isShutdown) { revert InvalidRequest(InvalidRequestReason.SHUTDOWN); } _; } function getShutdown() external view returns (bool) { return _loadVISlot().isShutdown; } function shutdown() external { require(msg.sender == owner()); //owner is "strategist" _loadVISlot().isShutdown = true; emit VaultShutdown(); } function domainSeparator() public view virtual returns (bytes32) { return keccak256( abi.encode( EIP_DOMAIN, VERSION, //version block.chainid, address(this) ) ); } function init(InitParams calldata params) external virtual { require(msg.sender == address(ROUTER())); VIData storage s = _loadVISlot(); if (params.delegate != address(0)) { s.delegate = params.delegate; } s.depositCap = params.depositCap; if (params.allowListEnabled) { s.allowListEnabled = true; uint256 i; for (; i < params.allowList.length; ) { s.allowList[params.allowList[i]] = true; unchecked { ++i; } } } } function setDelegate(address delegate_) external { require(msg.sender == owner()); //owner is "strategist" VIData storage s = _loadVISlot(); s.delegate = delegate_; emit DelegateUpdated(delegate_); } /** * @notice Retrieves the recipient of loan repayments. For PublicVaults (VAULT_TYPE 2), this is always the vault address. For PrivateVaults, retrieves the owner() of the vault. * @return The address of the recipient. */ function recipient() public view returns (address) { if (_isPublicVault()) { return address(this); } else { return owner(); } } function _isPublicVault() internal view returns (bool) { return IMPL_TYPE() == uint8(IAstariaRouter.ImplementationType.PublicVault); } function _handleProtocolFee(address feeTo, uint256 feeRake) internal { bool feeOn = feeTo != address(0); if (feeOn) { ERC20(asset()).safeTransfer(feeTo, feeRake); } } /** * @dev Generates a Lien for a valid loan commitment proof and sends the loan amount to the borrower. * @param amount the amount being paid * @param feeTo the protocol fee address if set * @param feeRake the protocol fee rake */ function _issuePayout( uint256 amount, address feeTo, uint256 feeRake ) internal { _handleProtocolFee(feeTo, feeRake); uint256 newAmount = amount - feeRake; ERC20(asset()).safeTransfer(address(ROUTER()), newAmount); } receive() external payable {} fallback() external payable {} }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {ERC20} from "solmate/tokens/ERC20.sol"; import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol"; import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol"; import {SafeCastLib} from "gpl/utils/SafeCastLib.sol"; import {ERC4626Cloned} from "gpl/ERC4626-Cloned.sol"; import {WithdrawVaultBase} from "core/WithdrawVaultBase.sol"; import {IWithdrawProxy} from "core/interfaces/IWithdrawProxy.sol"; import {PublicVault} from "core/PublicVault.sol"; import {IERC20Metadata} from "core/interfaces/IERC20Metadata.sol"; import {IERC4626} from "core/interfaces/IERC4626.sol"; import {LibString} from "solmate/utils/LibString.sol"; import {ERC721TokenReceiver} from "gpl/ERC721.sol"; import {IPublicVault} from "core/interfaces/IPublicVault.sol"; /** * @title WithdrawProxy * @notice This contract collects funds for liquidity providers who are exiting. When a liquidity provider is the first * in an epoch to mark that they would like to withdraw their funds, a WithdrawProxy for the liquidity provider's * PublicVault is deployed to collect loan repayments until the end of the next epoch. Users are minted WithdrawTokens * according to their balance in the protocol which are redeemable 1:1 for the underlying PublicVault asset by the end * of the next epoch. * */ contract WithdrawProxy is ERC4626Cloned, WithdrawVaultBase { using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; using SafeCastLib for uint256; event Claimed( address withdrawProxy, uint256 withdrawProxyAmount, address payable publicVault, uint256 publicVaultAmount ); uint256 private constant WITHDRAW_PROXY_SLOT = uint256(keccak256("xyz.astaria.WithdrawProxy.storage.location")) - 1; struct WPStorage { uint256 withdrawRatio; uint256 expected; // The sum of the remaining debt (amountOwed) accrued against the NFT at the timestamp when it is liquidated. yIntercept (virtual assets) of a PublicVault are not modified on liquidation, only once an auction is completed. uint40 finalAuctionEnd; // when this is deleted, we know the final auction is over uint256 withdrawReserveReceived; // amount received from PublicVault. The WETH balance of this contract - withdrawReserveReceived = amount received from liquidations. } enum InvalidStates { PROCESS_EPOCH_NOT_COMPLETE, FINAL_AUCTION_NOT_OVER, NOT_CLAIMED, CANT_CLAIM } error InvalidState(InvalidStates); function getState() public view returns ( uint256 withdrawRatio, uint256 expected, uint40 finalAuctionEnd, uint256 withdrawReserveReceived ) { WPStorage storage s = _loadSlot(); return ( s.withdrawRatio, s.expected, s.finalAuctionEnd, s.withdrawReserveReceived ); } function minDepositAmount() public view virtual override(ERC4626Cloned) returns (uint256) { return 0; } function decimals() public pure override returns (uint8) { return 18; } function asset() public pure override(ERC4626Cloned, WithdrawVaultBase) returns (address) { return super.asset(); } function totalAssets() public view override(ERC4626Cloned, IERC4626) returns (uint256) { return ERC20(asset()).balanceOf(address(this)); } /** * @notice Public view function to return the name of this WithdrawProxy. * @return The name of this WithdrawProxy. */ function name() public view override(IERC20Metadata, WithdrawVaultBase) returns (string memory) { return string( abi.encodePacked( "AST-WithdrawVault-", ERC20(asset()).symbol(), "-", LibString.toString(VAULT().epochEndTimestamp(CLAIMABLE_EPOCH())) ) ); } /** * @notice Public view function to return the symbol of this WithdrawProxy. * @return The symbol of this WithdrawProxy. */ function symbol() public view override(IERC20Metadata, WithdrawVaultBase) returns (string memory) { return string(abi.encodePacked("AST-WV-", ERC20(asset()).symbol())); } /** * @notice Mints WithdrawTokens for withdrawing liquidity providers, redeemable by the end of the next epoch. * @param receiver The receiver of the Withdraw Tokens. * @param shares The number of shares to mint. */ function mint( uint256 shares, address receiver ) public virtual override(ERC4626Cloned, IERC4626) onlyVault returns (uint256 assets) { _mint(receiver, shares); return shares; } function deposit( uint256 assets, address receiver ) public virtual override(ERC4626Cloned, IERC4626) onlyVault returns (uint256 shares) { revert NotSupported(); } modifier onlyWhenNoActiveAuction() { WPStorage storage s = _loadSlot(); // If auction funds have been collected to the WithdrawProxy // but the PublicVault hasn't claimed its share, too much money will be sent to LPs if (s.finalAuctionEnd != 0) { // if finalAuctionEnd is 0, no auctions were added revert InvalidState(InvalidStates.NOT_CLAIMED); } _; } function withdraw( uint256 assets, address receiver, address owner ) public virtual override(ERC4626Cloned, IERC4626) onlyWhenNoActiveAuction returns (uint256 shares) { return super.withdraw(assets, receiver, owner); } /** * @notice Redeem funds collected in the WithdrawProxy. * @param shares The number of WithdrawToken shares to redeem. * @param receiver The receiver of the underlying asset. * @param owner The owner of the WithdrawTokens. * @return assets The amount of the underlying asset redeemed. */ function redeem( uint256 shares, address receiver, address owner ) public virtual override(ERC4626Cloned, IERC4626) onlyWhenNoActiveAuction returns (uint256 assets) { return super.redeem(shares, receiver, owner); } function supportsInterface( bytes4 interfaceId ) external view virtual returns (bool) { return interfaceId == type(IWithdrawProxy).interfaceId; } function _loadSlot() internal pure returns (WPStorage storage s) { uint256 slot = WITHDRAW_PROXY_SLOT; assembly { s.slot := slot } } /** * @notice returns the final auctio nend */ function getFinalAuctionEnd() public view returns (uint256) { WPStorage storage s = _loadSlot(); return s.finalAuctionEnd; } /** * @notice returns the withdraw ratio */ function getWithdrawRatio() public view returns (uint256) { WPStorage storage s = _loadSlot(); return s.withdrawRatio; } /** * @notice returns the expected amount */ function getExpected() public view returns (uint256) { WPStorage storage s = _loadSlot(); return s.expected; } modifier onlyVault() { require(msg.sender == address(VAULT()), "only vault can call"); _; } /** * @notice Called when PublicVault sends a payment to the WithdrawProxy * to track how much of its WETH balance is from withdrawReserve payments instead of auction repayments * @param amount The amount paid by the PublicVault, deducted from its withdrawReserve. */ function increaseWithdrawReserveReceived(uint256 amount) external onlyVault { WPStorage storage s = _loadSlot(); s.withdrawReserveReceived += amount; } /** * @notice Return any excess funds to the PublicVault, according to the withdrawRatio between withdrawing and remaining LPs. */ function claim() public { WPStorage storage s = _loadSlot(); if (s.finalAuctionEnd == 0) { revert InvalidState(InvalidStates.CANT_CLAIM); } if (VAULT().getCurrentEpoch() < CLAIMABLE_EPOCH()) { revert InvalidState(InvalidStates.PROCESS_EPOCH_NOT_COMPLETE); } if (block.timestamp < s.finalAuctionEnd) { revert InvalidState(InvalidStates.FINAL_AUCTION_NOT_OVER); } uint256 balance = ERC20(asset()).balanceOf(address(this)) - s.withdrawReserveReceived; // will never underflow because withdrawReserveReceived is always increased by the transfer amount from the PublicVault uint256 decreaseInYIntercept = 0; if (balance < s.expected) { decreaseInYIntercept = (s.expected - balance).mulWadDown( 1e18 - s.withdrawRatio ); } else { balance = s.expected; } uint256 transferAmount = uint256(1e18 - s.withdrawRatio).mulDivUp( balance, 1e18 ); VAULT().updateVault( IPublicVault.UpdateVaultParams({ decreaseInYIntercept: decreaseInYIntercept, interestPaid: 0, decreaseInSlope: 0, amount: transferAmount, lienEnd: 0, isRepayment: false }) ); if (transferAmount > 0) { ERC20(asset()).safeTransfer(payable(address(VAULT())), transferAmount); } s.finalAuctionEnd = 0; emit Claimed( address(this), transferAmount, payable(address(VAULT())), balance ); } /** * @notice Called by PublicVault if previous epoch's withdrawReserve hasn't been met. * @param amount The amount to attempt to drain from the WithdrawProxy. * @param withdrawProxy The address of the withdrawProxy to drain to. */ function drain( uint256 amount, address withdrawProxy ) public onlyVault returns (uint256) { WPStorage storage s = _loadSlot(); uint256 balance = ERC20(asset()).balanceOf(address(this)); if (amount > balance) { amount = balance; } s.expected -= amount; ERC20(asset()).safeTransfer(withdrawProxy, amount); return amount; } /** * @notice Called at epoch boundary, computes the ratio between the funds of withdrawing liquidity providers and the balance of the underlying PublicVault so that claim() proportionally pays optimized-out to all parties. * @param liquidationWithdrawRatio The ratio of withdrawing to remaining LPs for the current epoch boundary. */ function setWithdrawRatio(uint256 liquidationWithdrawRatio) public onlyVault { _loadSlot().withdrawRatio = liquidationWithdrawRatio; } /** * @notice Called by PublicVault to set the expected amount of the asset to be received from the LienToken. * @param newLienExpectedValue the incoming expected value of the lien * @param finalAuctionDelta The amount of time to extend the final auction by if the LienToken is not redeemed. */ function handleNewLiquidation( uint256 newLienExpectedValue, uint256 finalAuctionDelta ) internal { WPStorage storage s = _loadSlot(); unchecked { s.expected += newLienExpectedValue; uint40 auctionEnd = (block.timestamp + finalAuctionDelta).safeCastTo40(); if (auctionEnd > s.finalAuctionEnd) s.finalAuctionEnd = auctionEnd; } } function onERC721Received( address _operator, address _from, uint256 tokenId, bytes calldata _data ) external virtual returns (bytes4) { // require( // msg.sender == address(VAULT().ROUTER().LIEN_TOKEN()), // "LienToken not msg.sender" // ); // require(_from == address(VAULT()), "only vault can call"); // require( // address(this) == VAULT().ROUTER().LIEN_TOKEN().ownerOf(tokenId), // "token not transferred" // ); uint256 expected; uint256 auctionEnd; (expected, auctionEnd) = abi.decode(_data, (uint256, uint256)); handleNewLiquidation(expected, auctionEnd); return ERC721TokenReceiver.onERC721Received.selector; } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IERC165} from "core/interfaces/IERC165.sol"; import {IERC4626} from "core/interfaces/IERC4626.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {IRouterBase} from "core/interfaces/IRouterBase.sol"; import {IPublicVault} from "core/interfaces/IPublicVault.sol"; interface IWithdrawProxy is IRouterBase, IERC165, IERC4626 { function VAULT() external pure returns (IPublicVault); function CLAIMABLE_EPOCH() external pure returns (uint64); function setWithdrawRatio(uint256 liquidationWithdrawRatio) external; function drain( uint256 amount, address withdrawProxy ) external returns (uint256); function claim() external; function getState() external view returns ( uint256 withdrawRatio, uint256 expected, uint40 finalAuctionEnd, uint256 withdrawReserveReceived ); function increaseWithdrawReserveReceived(uint256 amount) external; function getExpected() external view returns (uint256); function getWithdrawRatio() external view returns (uint256); function getFinalAuctionEnd() external view returns (uint256); error NotSupported(); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol) pragma solidity =0.8.17; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256 ret) { // (a + b - 1) / b can overflow on addition, so we distribute. assembly { if iszero(b) { revert(0, 0) } ret := add(div(a, b), gt(mod(a, b), 0x0)) } } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IERC165} from "core/interfaces/IERC165.sol"; import {IVaultImplementation} from "core/interfaces/IVaultImplementation.sol"; import {ILienToken} from "core/interfaces/ILienToken.sol"; import {IAstariaVaultBase} from "core/interfaces/IAstariaVaultBase.sol"; import {IWithdrawProxy} from "core/interfaces/IWithdrawProxy.sol"; interface IPublicVault is IVaultImplementation { struct EpochData { uint64 liensOpenForEpoch; address withdrawProxy; } struct VaultData { uint256 yIntercept; uint256 slope; uint40 last; uint64 currentEpoch; uint256 withdrawReserve; uint256 liquidationWithdrawRatio; uint256 balance; mapping(uint64 => EpochData) epochData; } struct UpdateVaultParams { uint256 decreaseInSlope; uint256 interestPaid; uint256 decreaseInYIntercept; uint256 amount; uint64 lienEnd; bool isRepayment; } struct AfterLiquidationParams { uint256 lienSlope; uint40 lienEnd; } function redeemFutureEpoch( uint256 shares, address receiver, address owner, uint64 epoch ) external returns (uint256 assets); function updateVault(UpdateVaultParams calldata params) external; function getSlope() external view returns (uint256); function getWithdrawReserve() external view returns (uint256); function getLiquidationWithdrawRatio() external view returns (uint256); function getYIntercept() external view returns (uint256); function getLienEpoch(uint64 end) external view returns (uint64); function getWithdrawProxy( uint64 epoch ) external view returns (IWithdrawProxy); function timeToEpochEnd() external view returns (uint256); function epochEndTimestamp(uint epoch) external pure returns (uint256); function transferWithdrawReserve() external; function processEpoch() external; function getCurrentEpoch() external view returns (uint64); function timeToSecondEpochEnd() external view returns (uint256); function stopLien( uint256 auctionWindow, uint256 lienSlope, uint64 lienEnd, uint256 tokenId, uint256 owed ) external; function getPublicVaultState() external view returns (uint256, uint256, uint40, uint64, uint256, uint256, uint256); function getEpochData(uint64 epoch) external view returns (uint, address); function getVirtualBalance() external view returns (uint256); // ERRORS error InvalidVaultState(InvalidVaultStates); error InvalidRedeemSize(); enum InvalidVaultStates { EPOCH_ENDED, EPOCH_TOO_LOW, EPOCH_TOO_HIGH, EPOCH_NOT_OVER, WITHDRAW_RESERVE_NOT_ZERO, WITHDRAW_RESERVE_UNDER_COLLATERALIZED, LIENS_OPEN_FOR_EPOCH_NOT_ZERO, LIQUIDATION_ACCOUNTANT_ALREADY_DEPLOYED_FOR_EPOCH, DEPOSIT_CAP_EXCEEDED, LOAN_GREATER_THAN_VIRTUAL_BALANCE } event StrategistFee(uint256 feeInShares); event LiensOpenForEpochRemaining(uint64 epoch, uint256 liensOpenForEpoch); event YInterceptChanged(uint256 newYintercept); event WithdrawReserveTransferred(uint256 amount); event WithdrawProxyDeployed(uint256 epoch, address withdrawProxy); event LienOpen(uint256 lienId, uint256 epoch); event SlopeUpdated(uint256 newSlope); event ProcessEpoch(address sender, uint256 currentEpoch); }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {ICollateralToken} from "core/interfaces/ICollateralToken.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {IRouterBase} from "core/interfaces/IRouterBase.sol"; interface IAstariaVaultBase is IRouterBase { function owner() external view returns (address); function asset() external view returns (address); function COLLATERAL_TOKEN() external view returns (ICollateralToken); function START() external view returns (uint256); function EPOCH_LENGTH() external view returns (uint256); function VAULT_FEE() external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IAstariaVaultBase} from "core/interfaces/IAstariaVaultBase.sol"; import {Clone} from "create2-clones-with-immutable-args/Clone.sol"; import {IERC4626} from "core/interfaces/IERC4626.sol"; import {ICollateralToken} from "core/interfaces/ICollateralToken.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {IRouterBase} from "core/interfaces/IRouterBase.sol"; abstract contract AstariaVaultBase is Clone, IAstariaVaultBase { function name() external view virtual returns (string memory); function symbol() external view virtual returns (string memory); function ROUTER() public pure returns (IAstariaRouter) { return IAstariaRouter(_getArgAddress(0)); //ends at 20 } function IMPL_TYPE() public pure returns (uint8) { return _getArgUint8(20); //ends at 21 } function owner() public pure returns (address) { return _getArgAddress(21); //ends at 41 } function asset() public pure virtual override(IAstariaVaultBase) returns (address) { return _getArgAddress(41); //ends at 41 } function START() public pure returns (uint256) { return _getArgUint256(61); // ends at 93 } function EPOCH_LENGTH() public pure returns (uint256) { return _getArgUint256(93); //ends at 125 } function VAULT_FEE() public pure returns (uint256) { return _getArgUint256(125); //ends at 157 } function COLLATERAL_TOKEN() public view returns (ICollateralToken) { return ROUTER().COLLATERAL_TOKEN(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity =0.8.17; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: BSD pragma solidity ^0.8.4; /// @title Clone /// @author zefram.eth /// @notice Provides helper functions for reading immutable args from calldata contract Clone { /// @notice Reads an immutable arg with type address /// @param argOffset The offset of the arg in the packed data /// @return arg The arg value function _getArgAddress(uint256 argOffset) internal pure returns (address arg) { uint256 offset = _getImmutableArgsOffset(); // solhint-disable-next-line no-inline-assembly assembly { arg := shr(0x60, calldataload(add(offset, argOffset))) } } /// @notice Reads an immutable arg with type uint256 /// @param argOffset The offset of the arg in the packed data /// @return arg The arg value function _getArgUint256(uint256 argOffset) internal pure returns (uint256 arg) { uint256 offset = _getImmutableArgsOffset(); // solhint-disable-next-line no-inline-assembly assembly { arg := calldataload(add(offset, argOffset)) } } /// @notice Reads a uint256 array stored in the immutable args. /// @param argOffset The offset of the arg in the packed data /// @param arrLen Number of elements in the array /// @return arr The array function _getArgUint256Array(uint256 argOffset, uint64 arrLen) internal pure returns (uint256[] memory arr) { uint256 offset = _getImmutableArgsOffset(); uint256 el; arr = new uint256[](arrLen); for (uint64 i = 0; i < arrLen; i++) { assembly { // solhint-disable-next-line no-inline-assembly el := calldataload(add(add(offset, argOffset), mul(i, 32))) } arr[i] = el; } return arr; } /// @notice Reads an immutable arg with type uint64 /// @param argOffset The offset of the arg in the packed data /// @return arg The arg value function _getArgUint64(uint256 argOffset) internal pure returns (uint64 arg) { uint256 offset = _getImmutableArgsOffset(); // solhint-disable-next-line no-inline-assembly assembly { arg := shr(0xc0, calldataload(add(offset, argOffset))) } } /// @notice Reads an immutable arg with type uint8 /// @param argOffset The offset of the arg in the packed data /// @return arg The arg value function _getArgUint8(uint256 argOffset) internal pure returns (uint8 arg) { uint256 offset = _getImmutableArgsOffset(); // solhint-disable-next-line no-inline-assembly assembly { arg := shr(0xf8, calldataload(add(offset, argOffset))) } } /// @return offset The offset of the packed immutable args in calldata function _getImmutableArgsOffset() internal pure returns (uint256 offset) { // solhint-disable-next-line no-inline-assembly assembly { offset := sub(calldatasize(), add(shr(240, calldataload(sub(calldatasize(), 2))), 2)) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; library Create2AddressDeriver { function deriveCreate2Address(address deployer, bytes32 salt, bytes memory initCode) internal pure returns (address) { return deriveCreate2AddressFromHash(deployer, salt, keccak256(initCode)); } function deriveCreate2AddressFromHash(address deployer, bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { return address( uint160( // downcast to match the address type. uint256( // convert to uint to truncate upper digits. keccak256( // compute the CREATE2 hash using 4 inputs. abi.encodePacked( // pack all inputs to the hash together. bytes1(0xff), // start with 0xff to distinguish from RLP. deployer, // this contract will be the caller. salt, // pass in the supplied salt value. initCodeHash // pass in the hash of initialization code. ) ) ) ) ); } }
pragma solidity =0.8.17; import {IERC165} from "core/interfaces/IERC165.sol"; interface IERC721 is IERC165 { event Transfer(address indexed from, address indexed to, uint256 indexed id); event Approval( address indexed owner, address indexed spender, uint256 indexed id ); event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); function tokenURI(uint256 id) external view returns (string memory); function ownerOf(uint256 id) external view returns (address owner); function balanceOf(address owner) external view returns (uint256 balance); function approve(address spender, uint256 id) external; function setApprovalForAll(address operator, bool approved) external; function transferFrom(address from, address to, uint256 id) external; function safeTransferFrom(address from, address to, uint256 id) external; function safeTransferFrom( address from, address to, uint256 id, bytes calldata data ) external; }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; interface ITransferProxy { function tokenTransferFrom( address token, address from, address to, uint256 amount ) external; function tokenTransferFromWithErrorReceiver( address token, address from, address to, uint256 amount ) external; }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IERC721} from "core/interfaces/IERC721.sol"; import {ITransferProxy} from "core/interfaces/ITransferProxy.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {ILienToken} from "core/interfaces/ILienToken.sol"; import { ConsiderationInterface } from "seaport-types/src/interfaces/ConsiderationInterface.sol"; import { ConduitControllerInterface } from "seaport-types/src/interfaces/ConduitControllerInterface.sol"; import {IERC1155} from "core/interfaces/IERC1155.sol"; import { Order, OrderParameters } from "seaport-types/src/lib/ConsiderationStructs.sol"; interface ICollateralToken is IERC721 { event AuctionPurchased(address buyer, uint256 lienId, uint256 price); event LiquidatorNFTClaimed(address liquidator, uint256 lienId); event ListedOnSeaport(uint256 collateralId, Order listingOrder); event FileUpdated(FileType what, bytes data); event Deposit721( address indexed tokenContract, uint256 indexed tokenId, uint256 indexed collateralId, address depositedFor ); event ReleaseTo( address indexed underlyingAsset, uint256 assetId, address indexed to ); struct Asset { address tokenContract; uint256 tokenId; bytes32 auctionHash; } struct CollateralStorage { ILienToken LIEN_TOKEN; IAstariaRouter ASTARIA_ROUTER; ConsiderationInterface SEAPORT; ConduitControllerInterface CONDUIT_CONTROLLER; address CONDUIT; bytes32 CONDUIT_KEY; //mapping of the collateralToken ID and its underlying asset mapping(uint256 => Asset) idToUnderlying; } struct ListUnderlyingForSaleParams { ILienToken.Stack stack; uint256 listPrice; uint56 maxDuration; } enum FileType { NotSupported, AstariaRouter, Seaport, CloseChannel } struct File { FileType what; bytes data; } function fileBatch(File[] calldata files) external; function file(File calldata incoming) external; function getConduit() external view returns (address); function getConduitKey() external view returns (bytes32); struct AuctionVaultParams { address settlementToken; uint256 collateralId; uint256 maxDuration; uint256 startingPrice; uint256 endingPrice; } function auctionVault( AuctionVaultParams calldata params ) external returns (OrderParameters memory); function SEAPORT() external view returns (ConsiderationInterface); function depositERC721( address tokenContract, uint256 tokenId, address from ) external; function CONDUIT_CONTROLLER() external view returns (ConduitControllerInterface); function getUnderlying( uint256 collateralId ) external view returns (address, uint256); function release(uint256 collateralId) external; function liquidatorNFTClaim( ILienToken.Stack memory stack, OrderParameters memory params ) external; error UnsupportedFile(); error InvalidCollateral(); error InvalidSender(); error InvalidOrder(); error InvalidCollateralState(InvalidCollateralStates); error ProtocolPaused(); error ListPriceTooLow(); error InvalidConduitKey(); error InvalidZoneHash(); error InvalidTarget(); error InvalidPaymentToken(); error InvalidPaymentAmount(); enum InvalidCollateralStates { AUCTION_ACTIVE, ID_MISMATCH, INVALID_AUCTION_PARAMS, ACTIVE_LIENS, ESCROW_ACTIVE, NO_AUCTION } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity =0.8.17; interface IPausable { function paused() external view returns (bool); } /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is IPausable { uint256 private constant PAUSE_SLOT = uint256(keccak256("xyz.astaria.AstariaRouter.Pausable.storage.location")) - 1; /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); struct PauseStorage { bool _paused; } function _loadPauseSlot() internal pure returns (PauseStorage storage s) { uint256 slot = PAUSE_SLOT; assembly { s.slot := slot } } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _loadPauseSlot()._paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _loadPauseSlot()._paused = true; emit Paused(msg.sender); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _loadPauseSlot()._paused = false; emit Unpaused(msg.sender); } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function getImpl(uint8) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { BasicOrderType, ItemType, OrderType, Side } from "./ConsiderationEnums.sol"; import { CalldataPointer, MemoryPointer } from "../helpers/PointerLibraries.sol"; /** * @dev An order contains eleven components: an offerer, a zone (or account that * can cancel the order or restrict who can fulfill the order depending on * the type), the order type (specifying partial fill support as well as * restricted order status), the start and end time, a hash that will be * provided to the zone when validating restricted orders, a salt, a key * corresponding to a given conduit, a counter, and an arbitrary number of * offer items that can be spent along with consideration items that must * be received by their respective recipient. */ struct OrderComponents { address offerer; address zone; OfferItem[] offer; ConsiderationItem[] consideration; OrderType orderType; uint256 startTime; uint256 endTime; bytes32 zoneHash; uint256 salt; bytes32 conduitKey; uint256 counter; } /** * @dev An offer item has five components: an item type (ETH or other native * tokens, ERC20, ERC721, and ERC1155, as well as criteria-based ERC721 and * ERC1155), a token address, a dual-purpose "identifierOrCriteria" * component that will either represent a tokenId or a merkle root * depending on the item type, and a start and end amount that support * increasing or decreasing amounts over the duration of the respective * order. */ struct OfferItem { ItemType itemType; address token; uint256 identifierOrCriteria; uint256 startAmount; uint256 endAmount; } /** * @dev A consideration item has the same five components as an offer item and * an additional sixth component designating the required recipient of the * item. */ struct ConsiderationItem { ItemType itemType; address token; uint256 identifierOrCriteria; uint256 startAmount; uint256 endAmount; address payable recipient; } /** * @dev A spent item is translated from a utilized offer item and has four * components: an item type (ETH or other native tokens, ERC20, ERC721, and * ERC1155), a token address, a tokenId, and an amount. */ struct SpentItem { ItemType itemType; address token; uint256 identifier; uint256 amount; } /** * @dev A received item is translated from a utilized consideration item and has * the same four components as a spent item, as well as an additional fifth * component designating the required recipient of the item. */ struct ReceivedItem { ItemType itemType; address token; uint256 identifier; uint256 amount; address payable recipient; } /** * @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155 * matching, a group of six functions may be called that only requires a * subset of the usual order arguments. Note the use of a "basicOrderType" * enum; this represents both the usual order type as well as the "route" * of the basic order (a simple derivation function for the basic order * type is `basicOrderType = orderType + (4 * basicOrderRoute)`.) */ struct BasicOrderParameters { // calldata offset address considerationToken; // 0x24 uint256 considerationIdentifier; // 0x44 uint256 considerationAmount; // 0x64 address payable offerer; // 0x84 address zone; // 0xa4 address offerToken; // 0xc4 uint256 offerIdentifier; // 0xe4 uint256 offerAmount; // 0x104 BasicOrderType basicOrderType; // 0x124 uint256 startTime; // 0x144 uint256 endTime; // 0x164 bytes32 zoneHash; // 0x184 uint256 salt; // 0x1a4 bytes32 offererConduitKey; // 0x1c4 bytes32 fulfillerConduitKey; // 0x1e4 uint256 totalOriginalAdditionalRecipients; // 0x204 AdditionalRecipient[] additionalRecipients; // 0x224 bytes signature; // 0x244 // Total length, excluding dynamic array data: 0x264 (580) } /** * @dev Basic orders can supply any number of additional recipients, with the * implied assumption that they are supplied from the offered ETH (or other * native token) or ERC20 token for the order. */ struct AdditionalRecipient { uint256 amount; address payable recipient; } /** * @dev The full set of order components, with the exception of the counter, * must be supplied when fulfilling more sophisticated orders or groups of * orders. The total number of original consideration items must also be * supplied, as the caller may specify additional consideration items. */ struct OrderParameters { address offerer; // 0x00 address zone; // 0x20 OfferItem[] offer; // 0x40 ConsiderationItem[] consideration; // 0x60 OrderType orderType; // 0x80 uint256 startTime; // 0xa0 uint256 endTime; // 0xc0 bytes32 zoneHash; // 0xe0 uint256 salt; // 0x100 bytes32 conduitKey; // 0x120 uint256 totalOriginalConsiderationItems; // 0x140 // offer.length // 0x160 } /** * @dev Orders require a signature in addition to the other order parameters. */ struct Order { OrderParameters parameters; bytes signature; } /** * @dev Advanced orders include a numerator (i.e. a fraction to attempt to fill) * and a denominator (the total size of the order) in addition to the * signature and other order parameters. It also supports an optional field * for supplying extra data; this data will be provided to the zone if the * order type is restricted and the zone is not the caller, or will be * provided to the offerer as context for contract order types. */ struct AdvancedOrder { OrderParameters parameters; uint120 numerator; uint120 denominator; bytes signature; bytes extraData; } /** * @dev Orders can be validated (either explicitly via `validate`, or as a * consequence of a full or partial fill), specifically cancelled (they can * also be cancelled in bulk via incrementing a per-zone counter), and * partially or fully filled (with the fraction filled represented by a * numerator and denominator). */ struct OrderStatus { bool isValidated; bool isCancelled; uint120 numerator; uint120 denominator; } /** * @dev A criteria resolver specifies an order, side (offer vs. consideration), * and item index. It then provides a chosen identifier (i.e. tokenId) * alongside a merkle proof demonstrating the identifier meets the required * criteria. */ struct CriteriaResolver { uint256 orderIndex; Side side; uint256 index; uint256 identifier; bytes32[] criteriaProof; } /** * @dev A fulfillment is applied to a group of orders. It decrements a series of * offer and consideration items, then generates a single execution * element. A given fulfillment can be applied to as many offer and * consideration items as desired, but must contain at least one offer and * at least one consideration that match. The fulfillment must also remain * consistent on all key parameters across all offer items (same offerer, * token, type, tokenId, and conduit preference) as well as across all * consideration items (token, type, tokenId, and recipient). */ struct Fulfillment { FulfillmentComponent[] offerComponents; FulfillmentComponent[] considerationComponents; } /** * @dev Each fulfillment component contains one index referencing a specific * order and another referencing a specific offer or consideration item. */ struct FulfillmentComponent { uint256 orderIndex; uint256 itemIndex; } /** * @dev An execution is triggered once all consideration items have been zeroed * out. It sends the item in question from the offerer to the item's * recipient, optionally sourcing approvals from either this contract * directly or from the offerer's chosen conduit if one is specified. An * execution is not provided as an argument, but rather is derived via * orders, criteria resolvers, and fulfillments (where the total number of * executions will be less than or equal to the total number of indicated * fulfillments) and returned as part of `matchOrders`. */ struct Execution { ReceivedItem item; address offerer; bytes32 conduitKey; } /** * @dev Restricted orders are validated post-execution by calling validateOrder * on the zone. This struct provides context about the order fulfillment * and any supplied extraData, as well as all order hashes fulfilled in a * call to a match or fulfillAvailable method. */ struct ZoneParameters { bytes32 orderHash; address fulfiller; address offerer; SpentItem[] offer; ReceivedItem[] consideration; bytes extraData; bytes32[] orderHashes; uint256 startTime; uint256 endTime; bytes32 zoneHash; } /** * @dev Zones and contract offerers can communicate which schemas they implement * along with any associated metadata related to each schema. */ struct Schema { uint256 id; bytes metadata; } using StructPointers for OrderComponents global; using StructPointers for OfferItem global; using StructPointers for ConsiderationItem global; using StructPointers for SpentItem global; using StructPointers for ReceivedItem global; using StructPointers for BasicOrderParameters global; using StructPointers for AdditionalRecipient global; using StructPointers for OrderParameters global; using StructPointers for Order global; using StructPointers for AdvancedOrder global; using StructPointers for OrderStatus global; using StructPointers for CriteriaResolver global; using StructPointers for Fulfillment global; using StructPointers for FulfillmentComponent global; using StructPointers for Execution global; using StructPointers for ZoneParameters global; /** * @dev This library provides a set of functions for converting structs to * pointers. */ library StructPointers { /** * @dev Get a MemoryPointer from OrderComponents. * * @param obj The OrderComponents object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( OrderComponents memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from OrderComponents. * * @param obj The OrderComponents object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( OrderComponents calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from OfferItem. * * @param obj The OfferItem object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( OfferItem memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from OfferItem. * * @param obj The OfferItem object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( OfferItem calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from ConsiderationItem. * * @param obj The ConsiderationItem object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( ConsiderationItem memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from ConsiderationItem. * * @param obj The ConsiderationItem object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( ConsiderationItem calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from SpentItem. * * @param obj The SpentItem object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( SpentItem memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from SpentItem. * * @param obj The SpentItem object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( SpentItem calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from ReceivedItem. * * @param obj The ReceivedItem object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( ReceivedItem memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from ReceivedItem. * * @param obj The ReceivedItem object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( ReceivedItem calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from BasicOrderParameters. * * @param obj The BasicOrderParameters object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( BasicOrderParameters memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from BasicOrderParameters. * * @param obj The BasicOrderParameters object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( BasicOrderParameters calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from AdditionalRecipient. * * @param obj The AdditionalRecipient object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( AdditionalRecipient memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from AdditionalRecipient. * * @param obj The AdditionalRecipient object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( AdditionalRecipient calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from OrderParameters. * * @param obj The OrderParameters object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( OrderParameters memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from OrderParameters. * * @param obj The OrderParameters object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( OrderParameters calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from Order. * * @param obj The Order object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( Order memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from Order. * * @param obj The Order object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( Order calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from AdvancedOrder. * * @param obj The AdvancedOrder object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( AdvancedOrder memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from AdvancedOrder. * * @param obj The AdvancedOrder object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( AdvancedOrder calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from OrderStatus. * * @param obj The OrderStatus object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( OrderStatus memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from OrderStatus. * * @param obj The OrderStatus object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( OrderStatus calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from CriteriaResolver. * * @param obj The CriteriaResolver object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( CriteriaResolver memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from CriteriaResolver. * * @param obj The CriteriaResolver object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( CriteriaResolver calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from Fulfillment. * * @param obj The Fulfillment object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( Fulfillment memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from Fulfillment. * * @param obj The Fulfillment object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( Fulfillment calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from FulfillmentComponent. * * @param obj The FulfillmentComponent object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( FulfillmentComponent memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from FulfillmentComponent. * * @param obj The FulfillmentComponent object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( FulfillmentComponent calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from Execution. * * @param obj The Execution object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( Execution memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from Execution. * * @param obj The Execution object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( Execution calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } /** * @dev Get a MemoryPointer from ZoneParameters. * * @param obj The ZoneParameters object. * * @return ptr The MemoryPointer. */ function toMemoryPointer( ZoneParameters memory obj ) internal pure returns (MemoryPointer ptr) { assembly { ptr := obj } } /** * @dev Get a CalldataPointer from ZoneParameters. * * @param obj The ZoneParameters object. * * @return ptr The CalldataPointer. */ function toCalldataPointer( ZoneParameters calldata obj ) internal pure returns (CalldataPointer ptr) { assembly { ptr := obj } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 indexed id); event Approval(address indexed owner, address indexed spender, uint256 indexed id); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /*////////////////////////////////////////////////////////////// METADATA STORAGE/LOGIC //////////////////////////////////////////////////////////////*/ string public name; string public symbol; function tokenURI(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) internal _ownerOf; mapping(address => uint256) internal _balanceOf; function ownerOf(uint256 id) public view virtual returns (address owner) { require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); } function balanceOf(address owner) public view virtual returns (uint256) { require(owner != address(0), "ZERO_ADDRESS"); return _balanceOf[owner]; } /*////////////////////////////////////////////////////////////// ERC721 APPROVAL STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) public getApproved; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(string memory _name, string memory _symbol) { name = _name; symbol = _symbol; } /*////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 id) public virtual { address owner = _ownerOf[id]; require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function transferFrom( address from, address to, uint256 id ) public virtual { require(from == _ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { _balanceOf[from]--; _balanceOf[to]++; } _ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom( address from, address to, uint256 id ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function safeTransferFrom( address from, address to, uint256 id, bytes calldata data ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); require(_ownerOf[id] == address(0), "ALREADY_MINTED"); // Counter overflow is incredibly unrealistic. unchecked { _balanceOf[to]++; } _ownerOf[id] = to; emit Transfer(address(0), to, id); } function _burn(uint256 id) internal virtual { address owner = _ownerOf[id]; require(owner != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { _balanceOf[owner]--; } delete _ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); } /*////////////////////////////////////////////////////////////// INTERNAL SAFE MINT LOGIC //////////////////////////////////////////////////////////////*/ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function _safeMint( address to, uint256 id, bytes memory data ) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721TokenReceiver { function onERC721Received( address, address, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC721TokenReceiver.onERC721Received.selector; } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IERC721} from "core/interfaces/IERC721.sol"; library CollateralLookup { function computeId( address token, uint256 tokenId ) internal pure returns (uint256 hash) { assembly { mstore(0, token) // sets the right most 20 bytes in the first memory slot. mstore(0x20, tokenId) // stores tokenId in the second memory slot. hash := keccak256(12, 52) // keccak from the 12th byte up to the entire second memory slot. } } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; pragma experimental ABIEncoderV2; import {Auth, Authority} from "solmate/auth/Auth.sol"; import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol"; import {ERC721, ERC721TokenReceiver} from "gpl/ERC721.sol"; import {IERC721} from "core/interfaces/IERC721.sol"; import {IERC165} from "core/interfaces/IERC165.sol"; import {ITransferProxy} from "core/interfaces/ITransferProxy.sol"; import {SafeCastLib} from "gpl/utils/SafeCastLib.sol"; import {CollateralLookup} from "core/libraries/CollateralLookup.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {ICollateralToken} from "core/interfaces/ICollateralToken.sol"; import {ILienToken} from "core/interfaces/ILienToken.sol"; import {IVaultImplementation} from "core/interfaces/IVaultImplementation.sol"; import {IPublicVault} from "core/interfaces/IPublicVault.sol"; import {VaultImplementation} from "./VaultImplementation.sol"; import {ERC20} from "solmate/tokens/ERC20.sol"; import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol"; import {AuthInitializable} from "core/AuthInitializable.sol"; import {Initializable} from "./utils/Initializable.sol"; import {AmountDeriver} from "seaport-core/src/lib/AmountDeriver.sol"; /** * @title LienToken * @notice This contract handles the creation, payments, buyouts, and liquidations of tokenized NFT-collateralized debt (liens). Vaults which originate loans against supported collateral are issued a LienToken representing the right to loan repayments and auctioned funds on liquidation. */ contract LienToken is ERC721, ILienToken, AuthInitializable, AmountDeriver { using FixedPointMathLib for uint256; using CollateralLookup for address; using SafeCastLib for uint256; using SafeTransferLib for ERC20; uint256 private constant LIEN_SLOT = uint256(keccak256("xyz.astaria.LienToken.storage.location")) - 1; constructor() { _disableInitializers(); } function initialize(Authority _AUTHORITY) public initializer { __initAuth(msg.sender, address(_AUTHORITY)); __initERC721("Astaria Lien Token", "ALT"); } function _loadLienStorageSlot() internal pure returns (LienStorage storage s) { uint256 slot = LIEN_SLOT; assembly { s.slot := slot } } /** * @notice Sets addresses for the AuctionHouse, CollateralToken, and AstariaRouter contracts to use. * @param incoming The incoming file to handle. */ function file(File calldata incoming) external requiresAuth { FileType what = incoming.what; bytes memory data = incoming.data; LienStorage storage s = _loadLienStorageSlot(); if (what == FileType.CollateralToken) { s.COLLATERAL_TOKEN = ICollateralToken(abi.decode(data, (address))); } else if (what == FileType.AstariaRouter) { s.ASTARIA_ROUTER = IAstariaRouter(abi.decode(data, (address))); } else { revert UnsupportedFile(); } emit FileUpdated(what, data); } function supportsInterface( bytes4 interfaceId ) public view override(ERC721, IERC165) returns (bool) { return interfaceId == type(ILienToken).interfaceId || super.supportsInterface(interfaceId); } /** * @notice Public view function that computes the interest for a LienToken since its last payment. * @param stack the Lien */ function getInterest(Stack calldata stack) public view returns (uint256) { return _getInterest(stack, block.timestamp); } /** * @dev Computes the interest accrued for a lien since its last payment. * @param stack The Lien for the loan to calculate interest for. * @param timestamp The timestamp at which to compute interest for. */ function _getInterest( Stack memory stack, uint256 timestamp ) internal pure returns (uint256) { uint256 delta_t = timestamp - stack.point.last; return (delta_t * stack.lien.details.rate).mulWadDown(stack.point.amount); } /** * @notice Checks the validity of the loan hash and the current state of the lien. */ modifier validateCollateralState(uint256 collateralId, bytes32 incomingHash) { LienStorage storage s = _loadLienStorageSlot(); if (incomingHash != s.collateralStateHash[collateralId]) { revert InvalidLienState(InvalidLienStates.INVALID_HASH); } _; } /** * @notice Stops accruing interest for all liens against a single CollateralToken. * @param auctionWindow The ID for the CollateralToken of the NFT used as collateral for the liens. * @param stack the stack of the loan * @param liquidator the address of the liquidator */ function handleLiquidation( uint256 auctionWindow, Stack calldata stack, address liquidator ) external validateCollateralState( stack.lien.collateralId, keccak256(abi.encode(stack)) ) { LienStorage storage s = _loadLienStorageSlot(); if (msg.sender != address(s.ASTARIA_ROUTER)) { revert InvalidSender(); } _handleLiquidation(s, auctionWindow, stack, liquidator); } function _handleLiquidation( LienStorage storage s, uint256 auctionWindow, Stack calldata stack, address liquidator ) internal { uint256 owed = _getOwed(stack, block.timestamp); uint256 lienId = uint256(keccak256(abi.encode(stack))); if ( s.collateralLiquidator[stack.lien.collateralId].liquidator != address(0) ) { revert InvalidLienState(InvalidLienStates.COLLATERAL_LIQUIDATED); } s.collateralLiquidator[stack.lien.collateralId] = AuctionData({ amountOwed: owed, liquidator: liquidator }); address owner = ownerOf(lienId); if (_isPublicVault(s, owner)) { IPublicVault(owner).stopLien( auctionWindow, calculateSlope(stack), stack.point.end, lienId, owed ); } } function tokenURI( uint256 tokenId ) public view override(ERC721, IERC721) returns (string memory) { require( ownerOf(tokenId) != address(0), "ERC721Metadata: URI query for nonexistent token" ); return string(abi.encodePacked("https://data.astaria.xyz/lien/", tokenId)); } function transferFrom( address from, address to, uint256 id ) public override(ERC721, IERC721) { LienStorage storage s = _loadLienStorageSlot(); if (_isPublicVault(s, to)) { revert InvalidLienState(InvalidLienStates.PUBLIC_VAULT_RECIPIENT); } super.transferFrom(from, to, id); } /** * @notice Creates a new lien against a CollateralToken. * @param params LienActionEncumber data containing CollateralToken information and lien parameters (rate, duration, and amount, rate, and debt caps). */ function createLien( ILienToken.LienActionEncumber calldata params ) external validateCollateralState(params.lien.collateralId, bytes32(0)) returns (uint256 lienId, Stack memory newStack, uint256 owingAtEnd) { LienStorage storage s = _loadLienStorageSlot(); if (msg.sender != address(s.ASTARIA_ROUTER)) { revert InvalidSender(); } (lienId, newStack) = _createLien(s, params); owingAtEnd = _getOwed(newStack, newStack.point.end); emit NewLien(params.lien.collateralId, newStack); } function _createLien( LienStorage storage s, ILienToken.LienActionEncumber calldata params ) internal returns (uint256 newLienId, ILienToken.Stack memory newSlot) { uint40 lienEnd = (block.timestamp + params.lien.details.duration) .safeCastTo40(); Point memory point = Point({ amount: params.amount, last: block.timestamp.safeCastTo40(), end: lienEnd }); newSlot = Stack({lien: params.lien, point: point}); newLienId = uint256(keccak256(abi.encode(newSlot))); s.collateralStateHash[newSlot.lien.collateralId] = bytes32(newLienId); _safeMint( params.receiver, newLienId, abi.encode( params.amount, lienEnd, calculateSlope(newSlot), params.feeTo, params.fee ) ); } /** * @notice Retrieves the liquidator for a CollateralToken. * @param collateralId The ID of the CollateralToken. */ function getAuctionLiquidator( uint256 collateralId ) external view returns (address liquidator) { liquidator = _loadLienStorageSlot() .collateralLiquidator[collateralId] .liquidator; if (liquidator == address(0)) { revert InvalidLienState(InvalidLienStates.COLLATERAL_NOT_LIQUIDATED); } } /** * @notice Retrieves the auctionData for a CollateralToken. * @param collateralId The ID of the CollateralToken. */ function getAuctionData( uint256 collateralId ) external view returns (AuctionData memory data) { data = _loadLienStorageSlot().collateralLiquidator[collateralId]; if (data.liquidator == address(0)) { revert InvalidLienState(InvalidLienStates.COLLATERAL_NOT_LIQUIDATED); } } /** * @notice Retrieves a lienCount for specific collateral * @param collateralId the Lien to compute a point for */ function getCollateralState( uint256 collateralId ) external view returns (bytes32) { return _loadLienStorageSlot().collateralStateHash[collateralId]; } struct Payments { uint256 amountOwing; uint256 interestPaid; uint256 decreaseInYIntercept; uint256 decreaseInSlope; } /** * @notice Make a payment for the debt against a CollateralToken. * @param stack the stack to pay against */ function makePayment( Stack calldata stack ) public validateCollateralState( stack.lien.collateralId, keccak256(abi.encode(stack)) ) { { LienStorage storage s = _loadLienStorageSlot(); Payments memory payment; //auction repayment bool isRepayment = false; if (s.collateralLiquidator[stack.lien.collateralId].amountOwed > 0) { if (msg.sender != address(s.COLLATERAL_TOKEN)) { revert InvalidSender(); } uint256 allowedSpendForPayment = ERC20(stack.lien.token).allowance( address(s.COLLATERAL_TOKEN), address(s.ASTARIA_ROUTER.TRANSFER_PROXY()) ); uint256 owing = s .collateralLiquidator[stack.lien.collateralId] .amountOwed; payment.amountOwing = owing > allowedSpendForPayment ? allowedSpendForPayment : owing; payment.interestPaid = payment.amountOwing > stack.point.amount ? payment.amountOwing - stack.point.amount : 0; payment.decreaseInYIntercept = owing - payment.amountOwing; payment.decreaseInSlope = 0; } else { // regular payment payment.amountOwing = _getOwed(stack, block.timestamp); // amountOwing payment.interestPaid = payment.amountOwing - stack.point.amount; // interestPaid payment.decreaseInYIntercept = 0; // decrease in y intercept payment.decreaseInSlope = calculateSlope(stack); isRepayment = true; } _payment( s, uint256(keccak256(abi.encode(stack))), stack.point.end, payment.amountOwing, payment.interestPaid, stack.lien.collateralId, stack.lien.token, payment.decreaseInYIntercept, // decrease in y intercept payment.decreaseInSlope, // decrease in slope isRepayment ); } } /** * @notice Computes the rate for a specified lien. * @param stack The Lien to compute the slope for. * @return slope The rate for the specified lien, in WETH per second. */ function calculateSlope(Stack memory stack) public pure returns (uint256) { return stack.lien.details.rate.mulWadDown(stack.point.amount); } /** * @notice Removes all liens for a given CollateralToken. * @param stack The Lien stack * @return the amount owed in uint192 at the current block.timestamp */ function getOwed(Stack memory stack) external view returns (uint256) { return _getOwed(stack, block.timestamp); } /** * @notice Removes all liens for a given CollateralToken. * @param stack The Lien stack * @param timestamp The timestamp to calculate the amount owed at * @return the amount owed in uint192 at the current block.timestamp */ function getOwed( Stack memory stack, uint256 timestamp ) external view returns (uint256) { return _getOwed(stack, timestamp); } /** * @dev Computes the debt owed to a Lien at a specified timestamp. * @param stack The specified Lien. * @return The amount owed to the Lien at the specified timestamp. */ function _getOwed( Stack memory stack, uint256 timestamp ) internal pure returns (uint256) { return stack.point.amount + _getInterest(stack, timestamp); } /** * @dev Make a payment from a payer to a specific lien against a CollateralToken. */ function _payment( LienStorage storage s, uint256 lienId, uint64 end, uint256 amountOwed, uint256 interestPaid, uint256 collateralId, address token, uint256 decreaseYIntercept, //remaining unpaid owed amount uint256 decreaseInSlope, bool isRepayment ) internal { address owner = ownerOf(lienId); if (_isPublicVault(s, owner)) { IPublicVault(owner).updateVault( IPublicVault.UpdateVaultParams({ decreaseInYIntercept: decreaseYIntercept, //if the lien owner is not the payee then we are not decreasing the y intercept interestPaid: interestPaid, decreaseInSlope: decreaseInSlope, amount: amountOwed, lienEnd: end, isRepayment: isRepayment }) ); } _removeLien(s, lienId, collateralId); if (amountOwed > 0) { s.ASTARIA_ROUTER.TRANSFER_PROXY().tokenTransferFromWithErrorReceiver( token, msg.sender, owner, amountOwed ); } //only if not in an auction if (msg.sender != address(s.COLLATERAL_TOKEN)) { emit Payment(lienId, amountOwed); s.COLLATERAL_TOKEN.release(collateralId); } } function _removeLien( LienStorage storage s, uint256 lienId, uint256 collateralId ) internal { _burn(lienId); delete s.collateralStateHash[collateralId]; delete s.collateralLiquidator[collateralId]; } function _isPublicVault( LienStorage storage s, address account ) internal view returns (bool) { return s.ASTARIA_ROUTER.isValidVault(account) && IPublicVault(account).supportsInterface(type(IPublicVault).interfaceId); } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {ILienToken} from "core/interfaces/ILienToken.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {IAstariaVaultBase} from "core/interfaces/IAstariaVaultBase.sol"; import {IERC165} from "core/interfaces/IERC165.sol"; interface IVaultImplementation is IAstariaVaultBase, IERC165 { enum InvalidRequestReason { NO_AUTHORITY, INVALID_SIGNATURE, INVALID_RATE, SHUTDOWN, PAUSED } error InvalidRequest(InvalidRequestReason reason); struct InitParams { address delegate; bool allowListEnabled; address[] allowList; uint256 depositCap; // max amount of tokens that can be deposited } struct VIData { uint256 depositCap; address delegate; bool allowListEnabled; bool isShutdown; uint256 strategistNonce; mapping(address => bool) allowList; } event AllowListUpdated(address, bool); event AllowListEnabled(bool); event DelegateUpdated(address); event NonceUpdated(uint256 nonce); event IncrementNonce(uint256 nonce); event VaultShutdown(); function getState() external view returns (uint256, address, address, bool, bool, uint256, bytes32); function getAllowList(address depositor) external view returns (bool); function getShutdown() external view returns (bool); function shutdown() external; function incrementNonce() external; function recipient() external view returns (address); function setDelegate(address delegate_) external; function init(InitParams calldata params) external; function domainSeparator() external view returns (bytes32); function modifyDepositCap(uint256 newCap) external; function getStrategistNonce() external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IRouterBase} from "core/interfaces/IRouterBase.sol"; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; import {IWithdrawProxy} from "core/interfaces/IWithdrawProxy.sol"; import {IERC4626} from "core/interfaces/IERC4626.sol"; import {Clone} from "create2-clones-with-immutable-args/Clone.sol"; import {IPublicVault} from "./interfaces/IPublicVault.sol"; abstract contract WithdrawVaultBase is Clone, IWithdrawProxy { function name() public view virtual returns (string memory); function symbol() public view virtual returns (string memory); function ROUTER() external pure returns (IAstariaRouter) { return IAstariaRouter(_getArgAddress(0)); } function IMPL_TYPE() public pure override(IRouterBase) returns (uint8) { return _getArgUint8(20); } function asset() public pure virtual override(IERC4626) returns (address) { return _getArgAddress(21); } function VAULT() public pure returns (IPublicVault) { return IPublicVault(_getArgAddress(41)); } function CLAIMABLE_EPOCH() public pure returns (uint64) { return _getArgUint64(61); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @notice Efficient library for creating string representations of integers. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) /// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) library LibString { function toString(int256 value) internal pure returns (string memory str) { if (value >= 0) return toString(uint256(value)); unchecked { str = toString(uint256(-value)); /// @solidity memory-safe-assembly assembly { // Note: This is only safe because we over-allocate memory // and write the string from right to left in toString(uint256), // and thus can be sure that sub(str, 1) is an unused memory location. let length := mload(str) // Load the string length. // Put the - character at the start of the string contents. mstore(str, 45) // 45 is the ASCII code for the - character. str := sub(str, 1) // Move back the string pointer by a byte. mstore(str, add(length, 1)) // Update the string length. } } } function toString(uint256 value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes // to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the // trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes. let newFreeMemoryPointer := add(mload(0x40), 160) // Update the free memory pointer to avoid overriding our string. mstore(0x40, newFreeMemoryPointer) // Assign str to the end of the zone of newly allocated memory. str := sub(newFreeMemoryPointer, 32) // Clean the last word of memory it may not be overwritten. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { // Move the pointer 1 byte to the left. str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing temp until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } // Compute and cache the final total length of the string. let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 32) // Store the string's length at the start of memory allocated for our string. mstore(str, length) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import {IERC721} from "core/interfaces/IERC721.sol"; import {Initializable} from "core/utils/Initializable.sol"; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721 is Initializable, IERC721 { /* ////////////////////////////////////////////////////////////// METADATA STORAGE/LOGIC ////////////////////////////////////////////////////////////// */ uint256 private constant ERC721_SLOT = uint256(keccak256("xyz.astaria.ERC721.storage.location")) - 1; struct ERC721Storage { string name; string symbol; mapping(uint256 => address) _ownerOf; mapping(address => uint256) _balanceOf; mapping(uint256 => address) getApproved; mapping(address => mapping(address => bool)) isApprovedForAll; } function getApproved(uint256 tokenId) public view returns (address) { return _loadERC721Slot().getApproved[tokenId]; } function isApprovedForAll(address owner, address operator) public view returns (bool) { return _loadERC721Slot().isApprovedForAll[owner][operator]; } function tokenURI(uint256 id) external view virtual returns (string memory); /* ////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE ////////////////////////////////////////////////////////////// */ function _loadERC721Slot() internal pure returns (ERC721Storage storage s) { uint256 slot = ERC721_SLOT; assembly { s.slot := slot } } function ownerOf(uint256 id) public view virtual returns (address owner) { require( (owner = _loadERC721Slot()._ownerOf[id]) != address(0), "NOT_MINTED" ); } function balanceOf(address owner) public view virtual returns (uint256) { require(owner != address(0), "ZERO_ADDRESS"); return _loadERC721Slot()._balanceOf[owner]; } /* ////////////////////////////////////////////////////////////// INITIALIZATION LOGIC ////////////////////////////////////////////////////////////// */ function __initERC721(string memory _name, string memory _symbol) internal { ERC721Storage storage s = _loadERC721Slot(); s.name = _name; s.symbol = _symbol; } /* ////////////////////////////////////////////////////////////// ERC721 LOGIC ////////////////////////////////////////////////////////////// */ function name() public view returns (string memory) { return _loadERC721Slot().name; } function symbol() public view returns (string memory) { return _loadERC721Slot().symbol; } function approve(address spender, uint256 id) external virtual { ERC721Storage storage s = _loadERC721Slot(); address owner = s._ownerOf[id]; require( msg.sender == owner || s.isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED" ); s.getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address operator, bool approved) external virtual { _loadERC721Slot().isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function transferFrom( address from, address to, uint256 id ) public virtual override(IERC721) { ERC721Storage storage s = _loadERC721Slot(); require(from == s._ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || s.isApprovedForAll[from][msg.sender] || msg.sender == s.getApproved[id], "NOT_AUTHORIZED" ); _transfer(from, to, id); } function _transfer( address from, address to, uint256 id ) internal { // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. ERC721Storage storage s = _loadERC721Slot(); unchecked { s._balanceOf[from]--; s._balanceOf[to]++; } s._ownerOf[id] = to; delete s.getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom( address from, address to, uint256 id ) external virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function safeTransferFrom( address from, address to, uint256 id, bytes calldata data ) external override(IERC721) { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } /* ////////////////////////////////////////////////////////////// ERC165 LOGIC ////////////////////////////////////////////////////////////// */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } /* ////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC ////////////////////////////////////////////////////////////// */ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); ERC721Storage storage s = _loadERC721Slot(); require(s._ownerOf[id] == address(0), "ALREADY_MINTED"); // Counter overflow is incredibly unrealistic. unchecked { s._balanceOf[to]++; } s._ownerOf[id] = to; emit Transfer(address(0), to, id); } function _burn(uint256 id) internal virtual { ERC721Storage storage s = _loadERC721Slot(); address owner = s._ownerOf[id]; require(owner != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { s._balanceOf[owner]--; } delete s._ownerOf[id]; delete s.getApproved[id]; emit Transfer(owner, address(0), id); } /* ////////////////////////////////////////////////////////////// INTERNAL SAFE MINT LOGIC ////////////////////////////////////////////////////////////// */ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received( msg.sender, address(0), id, "" ) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function _safeMint( address to, uint256 id, bytes memory data ) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received( msg.sender, address(0), id, data ) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721TokenReceiver { function onERC721Received( address, address, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC721TokenReceiver.onERC721Received.selector; } }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {IAstariaRouter} from "core/interfaces/IAstariaRouter.sol"; interface IRouterBase { function ROUTER() external view returns (IAstariaRouter); function IMPL_TYPE() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { AdvancedOrder, BasicOrderParameters, CriteriaResolver, Execution, Fulfillment, FulfillmentComponent, Order, OrderComponents } from "../lib/ConsiderationStructs.sol"; /** * @title ConsiderationInterface * @author 0age * @custom:version 1.5 * @notice Consideration is a generalized native token/ERC20/ERC721/ERC1155 * marketplace. It minimizes external calls to the greatest extent * possible and provides lightweight methods for common routes as well * as more flexible methods for composing advanced orders. * * @dev ConsiderationInterface contains all external function interfaces for * Consideration. */ interface ConsiderationInterface { /** * @notice Fulfill an order offering an ERC721 token by supplying Ether (or * the native token for the given chain) as consideration for the * order. An arbitrary number of "additional recipients" may also be * supplied which will each receive native tokens from the fulfiller * as consideration. * * @param parameters Additional information on the fulfilled order. Note * that the offerer must first approve this contract (or * their preferred conduit if indicated by the order) for * their offered ERC721 token to be transferred. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillBasicOrder( BasicOrderParameters calldata parameters ) external payable returns (bool fulfilled); /** * @notice Fulfill an order with an arbitrary number of items for offer and * consideration. Note that this function does not support * criteria-based orders or partial filling of orders (though * filling the remainder of a partially-filled order is supported). * * @param order The order to fulfill. Note that both the * offerer and the fulfiller must first approve * this contract (or the corresponding conduit if * indicated) to transfer any relevant tokens on * their behalf and that contracts must implement * `onERC1155Received` to receive ERC1155 tokens * as consideration. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used, with direct approvals set on * Consideration. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillOrder( Order calldata order, bytes32 fulfillerConduitKey ) external payable returns (bool fulfilled); /** * @notice Fill an order, fully or partially, with an arbitrary number of * items for offer and consideration alongside criteria resolvers * containing specific token identifiers and associated proofs. * * @param advancedOrder The order to fulfill along with the fraction * of the order to attempt to fill. Note that * both the offerer and the fulfiller must first * approve this contract (or their preferred * conduit if indicated by the order) to transfer * any relevant tokens on their behalf and that * contracts must implement `onERC1155Received` * to receive ERC1155 tokens as consideration. * Also note that all offer and consideration * components must have no remainder after * multiplication of the respective amount with * the supplied fraction for the partial fill to * be considered valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a proof * that the supplied token identifier is * contained in the merkle root held by the item * in question's criteria element. Note that an * empty criteria indicates that any * (transferable) token identifier on the token * in question is valid and that no associated * proof needs to be supplied. * @param fulfillerConduitKey A bytes32 value indicating what conduit, if * any, to source the fulfiller's token approvals * from. The zero hash signifies that no conduit * should be used, with direct approvals set on * Consideration. * @param recipient The intended recipient for all received items, * with `address(0)` indicating that the caller * should receive the items. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillAdvancedOrder( AdvancedOrder calldata advancedOrder, CriteriaResolver[] calldata criteriaResolvers, bytes32 fulfillerConduitKey, address recipient ) external payable returns (bool fulfilled); /** * @notice Attempt to fill a group of orders, each with an arbitrary number * of items for offer and consideration. Any order that is not * currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * Note that this function does not support criteria-based orders or * partial filling of orders (though filling the remainder of a * partially-filled order is supported). * * @param orders The orders to fulfill. Note that both * the offerer and the fulfiller must first * approve this contract (or the * corresponding conduit if indicated) to * transfer any relevant tokens on their * behalf and that contracts must implement * `onERC1155Received` to receive ERC1155 * tokens as consideration. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used, with * direct approvals set on this contract. * @param maximumFulfilled The maximum number of orders to fulfill. * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of * this array. */ function fulfillAvailableOrders( Order[] calldata orders, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, uint256 maximumFulfilled ) external payable returns (bool[] memory availableOrders, Execution[] memory executions); /** * @notice Attempt to fill a group of orders, fully or partially, with an * arbitrary number of items for offer and consideration per order * alongside criteria resolvers containing specific token * identifiers and associated proofs. Any order that is not * currently active, has already been fully filled, or has been * cancelled will be omitted. Remaining offer and consideration * items will then be aggregated where possible as indicated by the * supplied offer and consideration component arrays and aggregated * items will be transferred to the fulfiller or to each intended * recipient, respectively. Note that a failing item transfer or an * issue with order formatting will cause the entire batch to fail. * * @param advancedOrders The orders to fulfill along with the * fraction of those orders to attempt to * fill. Note that both the offerer and the * fulfiller must first approve this * contract (or their preferred conduit if * indicated by the order) to transfer any * relevant tokens on their behalf and that * contracts must implement * `onERC1155Received` to enable receipt of * ERC1155 tokens as consideration. Also * note that all offer and consideration * components must have no remainder after * multiplication of the respective amount * with the supplied fraction for an * order's partial fill amount to be * considered valid. * @param criteriaResolvers An array where each element contains a * reference to a specific offer or * consideration, a token identifier, and a * proof that the supplied token identifier * is contained in the merkle root held by * the item in question's criteria element. * Note that an empty criteria indicates * that any (transferable) token * identifier on the token in question is * valid and that no associated proof needs * to be supplied. * @param offerFulfillments An array of FulfillmentComponent arrays * indicating which offer items to attempt * to aggregate when preparing executions. * @param considerationFulfillments An array of FulfillmentComponent arrays * indicating which consideration items to * attempt to aggregate when preparing * executions. * @param fulfillerConduitKey A bytes32 value indicating what conduit, * if any, to source the fulfiller's token * approvals from. The zero hash signifies * that no conduit should be used, with * direct approvals set on this contract. * @param recipient The intended recipient for all received * items, with `address(0)` indicating that * the caller should receive the items. * @param maximumFulfilled The maximum number of orders to fulfill. * * @return availableOrders An array of booleans indicating if each order * with an index corresponding to the index of the * returned boolean was fulfillable or not. * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of * this array. */ function fulfillAvailableAdvancedOrders( AdvancedOrder[] calldata advancedOrders, CriteriaResolver[] calldata criteriaResolvers, FulfillmentComponent[][] calldata offerFulfillments, FulfillmentComponent[][] calldata considerationFulfillments, bytes32 fulfillerConduitKey, address recipient, uint256 maximumFulfilled ) external payable returns (bool[] memory availableOrders, Execution[] memory executions); /** * @notice Match an arbitrary number of orders, each with an arbitrary * number of items for offer and consideration along with a set of * fulfillments allocating offer components to consideration * components. Note that this function does not support * criteria-based or partial filling of orders (though filling the * remainder of a partially-filled order is supported). Any unspent * offer item amounts or native tokens will be transferred to the * caller. * * @param orders The orders to match. Note that both the offerer and * fulfiller on each order must first approve this * contract (or their conduit if indicated by the order) * to transfer any relevant tokens on their behalf and * each consideration recipient must implement * `onERC1155Received` to enable ERC1155 token receipt. * @param fulfillments An array of elements allocating offer components to * consideration components. Note that each * consideration component must be fully met for the * match operation to be valid. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or * native tokens will not be reflected as part of this * array. */ function matchOrders( Order[] calldata orders, Fulfillment[] calldata fulfillments ) external payable returns (Execution[] memory executions); /** * @notice Match an arbitrary number of full or partial orders, each with an * arbitrary number of items for offer and consideration, supplying * criteria resolvers containing specific token identifiers and * associated proofs as well as fulfillments allocating offer * components to consideration components. Any unspent offer item * amounts will be transferred to the designated recipient (with the * null address signifying to use the caller) and any unspent native * tokens will be returned to the caller. * * @param orders The advanced orders to match. Note that both the * offerer and fulfiller on each order must first * approve this contract (or a preferred conduit if * indicated by the order) to transfer any relevant * tokens on their behalf and each consideration * recipient must implement `onERC1155Received` in * order to receive ERC1155 tokens. Also note that * the offer and consideration components for each * order must have no remainder after multiplying * the respective amount with the supplied fraction * in order for the group of partial fills to be * considered valid. * @param criteriaResolvers An array where each element contains a reference * to a specific order as well as that order's * offer or consideration, a token identifier, and * a proof that the supplied token identifier is * contained in the order's merkle root. Note that * an empty root indicates that any (transferable) * token identifier is valid and that no associated * proof needs to be supplied. * @param fulfillments An array of elements allocating offer components * to consideration components. Note that each * consideration component must be fully met in * order for the match operation to be valid. * @param recipient The intended recipient for all unspent offer * item amounts, or the caller if the null address * is supplied. * * @return executions An array of elements indicating the sequence of * transfers performed as part of matching the given * orders. Note that unspent offer item amounts or native * tokens will not be reflected as part of this array. */ function matchAdvancedOrders( AdvancedOrder[] calldata orders, CriteriaResolver[] calldata criteriaResolvers, Fulfillment[] calldata fulfillments, address recipient ) external payable returns (Execution[] memory executions); /** * @notice Cancel an arbitrary number of orders. Note that only the offerer * or the zone of a given order may cancel it. Callers should ensure * that the intended order was cancelled by calling `getOrderStatus` * and confirming that `isCancelled` returns `true`. * * @param orders The orders to cancel. * * @return cancelled A boolean indicating whether the supplied orders have * been successfully cancelled. */ function cancel( OrderComponents[] calldata orders ) external returns (bool cancelled); /** * @notice Validate an arbitrary number of orders, thereby registering their * signatures as valid and allowing the fulfiller to skip signature * verification on fulfillment. Note that validated orders may still * be unfulfillable due to invalid item amounts or other factors; * callers should determine whether validated orders are fulfillable * by simulating the fulfillment call prior to execution. Also note * that anyone can validate a signed order, but only the offerer can * validate an order without supplying a signature. * * @param orders The orders to validate. * * @return validated A boolean indicating whether the supplied orders have * been successfully validated. */ function validate( Order[] calldata orders ) external returns (bool validated); /** * @notice Cancel all orders from a given offerer with a given zone in bulk * by incrementing a counter. Note that only the offerer may * increment the counter. * * @return newCounter The new counter. */ function incrementCounter() external returns (uint256 newCounter); /** * @notice Fulfill an order offering an ERC721 token by supplying Ether (or * the native token for the given chain) as consideration for the * order. An arbitrary number of "additional recipients" may also be * supplied which will each receive native tokens from the fulfiller * as consideration. Note that this function costs less gas than * `fulfillBasicOrder` due to the zero bytes in the function * selector (0x00000000) which also results in earlier function * dispatch. * * @param parameters Additional information on the fulfilled order. Note * that the offerer must first approve this contract (or * their preferred conduit if indicated by the order) for * their offered ERC721 token to be transferred. * * @return fulfilled A boolean indicating whether the order has been * successfully fulfilled. */ function fulfillBasicOrder_efficient_6GL6yc( BasicOrderParameters calldata parameters ) external payable returns (bool fulfilled); /** * @notice Retrieve the order hash for a given order. * * @param order The components of the order. * * @return orderHash The order hash. */ function getOrderHash( OrderComponents calldata order ) external view returns (bytes32 orderHash); /** * @notice Retrieve the status of a given order by hash, including whether * the order has been cancelled or validated and the fraction of the * order that has been filled. * * @param orderHash The order hash in question. * * @return isValidated A boolean indicating whether the order in question * has been validated (i.e. previously approved or * partially filled). * @return isCancelled A boolean indicating whether the order in question * has been cancelled. * @return totalFilled The total portion of the order that has been filled * (i.e. the "numerator"). * @return totalSize The total size of the order that is either filled or * unfilled (i.e. the "denominator"). */ function getOrderStatus( bytes32 orderHash ) external view returns ( bool isValidated, bool isCancelled, uint256 totalFilled, uint256 totalSize ); /** * @notice Retrieve the current counter for a given offerer. * * @param offerer The offerer in question. * * @return counter The current counter. */ function getCounter( address offerer ) external view returns (uint256 counter); /** * @notice Retrieve configuration information for this contract. * * @return version The contract version. * @return domainSeparator The domain separator for this contract. * @return conduitController The conduit Controller set for this contract. */ function information() external view returns ( string memory version, bytes32 domainSeparator, address conduitController ); function getContractOffererNonce( address contractOfferer ) external view returns (uint256 nonce); /** * @notice Retrieve the name of this contract. * * @return contractName The name of this contract. */ function name() external view returns (string memory contractName); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title ConduitControllerInterface * @author 0age * @notice ConduitControllerInterface contains all external function interfaces, * structs, events, and errors for the conduit controller. */ interface ConduitControllerInterface { /** * @dev Track the conduit key, current owner, new potential owner, and open * channels for each deployed conduit. */ struct ConduitProperties { bytes32 key; address owner; address potentialOwner; address[] channels; mapping(address => uint256) channelIndexesPlusOne; } /** * @dev Emit an event whenever a new conduit is created. * * @param conduit The newly created conduit. * @param conduitKey The conduit key used to create the new conduit. */ event NewConduit(address conduit, bytes32 conduitKey); /** * @dev Emit an event whenever conduit ownership is transferred. * * @param conduit The conduit for which ownership has been * transferred. * @param previousOwner The previous owner of the conduit. * @param newOwner The new owner of the conduit. */ event OwnershipTransferred( address indexed conduit, address indexed previousOwner, address indexed newOwner ); /** * @dev Emit an event whenever a conduit owner registers a new potential * owner for that conduit. * * @param newPotentialOwner The new potential owner of the conduit. */ event PotentialOwnerUpdated(address indexed newPotentialOwner); /** * @dev Revert with an error when attempting to create a new conduit using a * conduit key where the first twenty bytes of the key do not match the * address of the caller. */ error InvalidCreator(); /** * @dev Revert with an error when attempting to create a new conduit when no * initial owner address is supplied. */ error InvalidInitialOwner(); /** * @dev Revert with an error when attempting to set a new potential owner * that is already set. */ error NewPotentialOwnerAlreadySet( address conduit, address newPotentialOwner ); /** * @dev Revert with an error when attempting to cancel ownership transfer * when no new potential owner is currently set. */ error NoPotentialOwnerCurrentlySet(address conduit); /** * @dev Revert with an error when attempting to interact with a conduit that * does not yet exist. */ error NoConduit(); /** * @dev Revert with an error when attempting to create a conduit that * already exists. */ error ConduitAlreadyExists(address conduit); /** * @dev Revert with an error when attempting to update channels or transfer * ownership of a conduit when the caller is not the owner of the * conduit in question. */ error CallerIsNotOwner(address conduit); /** * @dev Revert with an error when attempting to register a new potential * owner and supplying the null address. */ error NewPotentialOwnerIsZeroAddress(address conduit); /** * @dev Revert with an error when attempting to claim ownership of a conduit * with a caller that is not the current potential owner for the * conduit in question. */ error CallerIsNotNewPotentialOwner(address conduit); /** * @dev Revert with an error when attempting to retrieve a channel using an * index that is out of range. */ error ChannelOutOfRange(address conduit); /** * @notice Deploy a new conduit using a supplied conduit key and assigning * an initial owner for the deployed conduit. Note that the first * twenty bytes of the supplied conduit key must match the caller * and that a new conduit cannot be created if one has already been * deployed using the same conduit key. * * @param conduitKey The conduit key used to deploy the conduit. Note that * the first twenty bytes of the conduit key must match * the caller of this contract. * @param initialOwner The initial owner to set for the new conduit. * * @return conduit The address of the newly deployed conduit. */ function createConduit( bytes32 conduitKey, address initialOwner ) external returns (address conduit); /** * @notice Open or close a channel on a given conduit, thereby allowing the * specified account to execute transfers against that conduit. * Extreme care must be taken when updating channels, as malicious * or vulnerable channels can transfer any ERC20, ERC721 and ERC1155 * tokens where the token holder has granted the conduit approval. * Only the owner of the conduit in question may call this function. * * @param conduit The conduit for which to open or close the channel. * @param channel The channel to open or close on the conduit. * @param isOpen A boolean indicating whether to open or close the channel. */ function updateChannel( address conduit, address channel, bool isOpen ) external; /** * @notice Initiate conduit ownership transfer by assigning a new potential * owner for the given conduit. Once set, the new potential owner * may call `acceptOwnership` to claim ownership of the conduit. * Only the owner of the conduit in question may call this function. * * @param conduit The conduit for which to initiate ownership transfer. * @param newPotentialOwner The new potential owner of the conduit. */ function transferOwnership( address conduit, address newPotentialOwner ) external; /** * @notice Clear the currently set potential owner, if any, from a conduit. * Only the owner of the conduit in question may call this function. * * @param conduit The conduit for which to cancel ownership transfer. */ function cancelOwnershipTransfer(address conduit) external; /** * @notice Accept ownership of a supplied conduit. Only accounts that the * current owner has set as the new potential owner may call this * function. * * @param conduit The conduit for which to accept ownership. */ function acceptOwnership(address conduit) external; /** * @notice Retrieve the current owner of a deployed conduit. * * @param conduit The conduit for which to retrieve the associated owner. * * @return owner The owner of the supplied conduit. */ function ownerOf(address conduit) external view returns (address owner); /** * @notice Retrieve the conduit key for a deployed conduit via reverse * lookup. * * @param conduit The conduit for which to retrieve the associated conduit * key. * * @return conduitKey The conduit key used to deploy the supplied conduit. */ function getKey(address conduit) external view returns (bytes32 conduitKey); /** * @notice Derive the conduit associated with a given conduit key and * determine whether that conduit exists (i.e. whether it has been * deployed). * * @param conduitKey The conduit key used to derive the conduit. * * @return conduit The derived address of the conduit. * @return exists A boolean indicating whether the derived conduit has been * deployed or not. */ function getConduit( bytes32 conduitKey ) external view returns (address conduit, bool exists); /** * @notice Retrieve the potential owner, if any, for a given conduit. The * current owner may set a new potential owner via * `transferOwnership` and that owner may then accept ownership of * the conduit in question via `acceptOwnership`. * * @param conduit The conduit for which to retrieve the potential owner. * * @return potentialOwner The potential owner, if any, for the conduit. */ function getPotentialOwner( address conduit ) external view returns (address potentialOwner); /** * @notice Retrieve the status (either open or closed) of a given channel on * a conduit. * * @param conduit The conduit for which to retrieve the channel status. * @param channel The channel for which to retrieve the status. * * @return isOpen The status of the channel on the given conduit. */ function getChannelStatus( address conduit, address channel ) external view returns (bool isOpen); /** * @notice Retrieve the total number of open channels for a given conduit. * * @param conduit The conduit for which to retrieve the total channel count. * * @return totalChannels The total number of open channels for the conduit. */ function getTotalChannels( address conduit ) external view returns (uint256 totalChannels); /** * @notice Retrieve an open channel at a specific index for a given conduit. * Note that the index of a channel can change as a result of other * channels being closed on the conduit. * * @param conduit The conduit for which to retrieve the open channel. * @param channelIndex The index of the channel in question. * * @return channel The open channel, if any, at the specified channel index. */ function getChannel( address conduit, uint256 channelIndex ) external view returns (address channel); /** * @notice Retrieve all open channels for a given conduit. Note that calling * this function for a conduit with many channels will revert with * an out-of-gas error. * * @param conduit The conduit for which to retrieve open channels. * * @return channels An array of open channels on the given conduit. */ function getChannels( address conduit ) external view returns (address[] memory channels); /** * @dev Retrieve the conduit creation code and runtime code hashes. */ function getConduitCodeHashes() external view returns (bytes32 creationCodeHash, bytes32 runtimeCodeHash); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol) pragma solidity =0.8.17; import {IERC165} from "core/interfaces/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value ); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll( address indexed account, address indexed operator, bool approved ); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf( address account, uint256 id ) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll( address account, address operator ) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; enum OrderType { // 0: no partial fills, anyone can execute FULL_OPEN, // 1: partial fills supported, anyone can execute PARTIAL_OPEN, // 2: no partial fills, only offerer or zone can execute FULL_RESTRICTED, // 3: partial fills supported, only offerer or zone can execute PARTIAL_RESTRICTED, // 4: contract order type CONTRACT } enum BasicOrderType { // 0: no partial fills, anyone can execute ETH_TO_ERC721_FULL_OPEN, // 1: partial fills supported, anyone can execute ETH_TO_ERC721_PARTIAL_OPEN, // 2: no partial fills, only offerer or zone can execute ETH_TO_ERC721_FULL_RESTRICTED, // 3: partial fills supported, only offerer or zone can execute ETH_TO_ERC721_PARTIAL_RESTRICTED, // 4: no partial fills, anyone can execute ETH_TO_ERC1155_FULL_OPEN, // 5: partial fills supported, anyone can execute ETH_TO_ERC1155_PARTIAL_OPEN, // 6: no partial fills, only offerer or zone can execute ETH_TO_ERC1155_FULL_RESTRICTED, // 7: partial fills supported, only offerer or zone can execute ETH_TO_ERC1155_PARTIAL_RESTRICTED, // 8: no partial fills, anyone can execute ERC20_TO_ERC721_FULL_OPEN, // 9: partial fills supported, anyone can execute ERC20_TO_ERC721_PARTIAL_OPEN, // 10: no partial fills, only offerer or zone can execute ERC20_TO_ERC721_FULL_RESTRICTED, // 11: partial fills supported, only offerer or zone can execute ERC20_TO_ERC721_PARTIAL_RESTRICTED, // 12: no partial fills, anyone can execute ERC20_TO_ERC1155_FULL_OPEN, // 13: partial fills supported, anyone can execute ERC20_TO_ERC1155_PARTIAL_OPEN, // 14: no partial fills, only offerer or zone can execute ERC20_TO_ERC1155_FULL_RESTRICTED, // 15: partial fills supported, only offerer or zone can execute ERC20_TO_ERC1155_PARTIAL_RESTRICTED, // 16: no partial fills, anyone can execute ERC721_TO_ERC20_FULL_OPEN, // 17: partial fills supported, anyone can execute ERC721_TO_ERC20_PARTIAL_OPEN, // 18: no partial fills, only offerer or zone can execute ERC721_TO_ERC20_FULL_RESTRICTED, // 19: partial fills supported, only offerer or zone can execute ERC721_TO_ERC20_PARTIAL_RESTRICTED, // 20: no partial fills, anyone can execute ERC1155_TO_ERC20_FULL_OPEN, // 21: partial fills supported, anyone can execute ERC1155_TO_ERC20_PARTIAL_OPEN, // 22: no partial fills, only offerer or zone can execute ERC1155_TO_ERC20_FULL_RESTRICTED, // 23: partial fills supported, only offerer or zone can execute ERC1155_TO_ERC20_PARTIAL_RESTRICTED } enum BasicOrderRouteType { // 0: provide Ether (or other native token) to receive offered ERC721 item. ETH_TO_ERC721, // 1: provide Ether (or other native token) to receive offered ERC1155 item. ETH_TO_ERC1155, // 2: provide ERC20 item to receive offered ERC721 item. ERC20_TO_ERC721, // 3: provide ERC20 item to receive offered ERC1155 item. ERC20_TO_ERC1155, // 4: provide ERC721 item to receive offered ERC20 item. ERC721_TO_ERC20, // 5: provide ERC1155 item to receive offered ERC20 item. ERC1155_TO_ERC20 } enum ItemType { // 0: ETH on mainnet, MATIC on polygon, etc. NATIVE, // 1: ERC20 items (ERC777 and ERC20 analogues could also technically work) ERC20, // 2: ERC721 items ERC721, // 3: ERC1155 items ERC1155, // 4: ERC721 items where a number of tokenIds are supported ERC721_WITH_CRITERIA, // 5: ERC1155 items where a number of ids are supported ERC1155_WITH_CRITERIA } enum Side { // 0: Items that can be spent OFFER, // 1: Items that must be received CONSIDERATION }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; type CalldataPointer is uint256; type ReturndataPointer is uint256; type MemoryPointer is uint256; using CalldataPointerLib for CalldataPointer global; using MemoryPointerLib for MemoryPointer global; using ReturndataPointerLib for ReturndataPointer global; using CalldataReaders for CalldataPointer global; using ReturndataReaders for ReturndataPointer global; using MemoryReaders for MemoryPointer global; using MemoryWriters for MemoryPointer global; CalldataPointer constant CalldataStart = CalldataPointer.wrap(0x04); MemoryPointer constant FreeMemoryPPtr = MemoryPointer.wrap(0x40); uint256 constant IdentityPrecompileAddress = 0x4; uint256 constant OffsetOrLengthMask = 0xffffffff; uint256 constant _OneWord = 0x20; uint256 constant _FreeMemoryPointerSlot = 0x40; /// @dev Allocates `size` bytes in memory by increasing the free memory pointer /// and returns the memory pointer to the first byte of the allocated region. // (Free functions cannot have visibility.) // solhint-disable-next-line func-visibility function malloc(uint256 size) pure returns (MemoryPointer mPtr) { assembly { mPtr := mload(_FreeMemoryPointerSlot) mstore(_FreeMemoryPointerSlot, add(mPtr, size)) } } // (Free functions cannot have visibility.) // solhint-disable-next-line func-visibility function getFreeMemoryPointer() pure returns (MemoryPointer mPtr) { mPtr = FreeMemoryPPtr.readMemoryPointer(); } // (Free functions cannot have visibility.) // solhint-disable-next-line func-visibility function setFreeMemoryPointer(MemoryPointer mPtr) pure { FreeMemoryPPtr.write(mPtr); } library CalldataPointerLib { function lt( CalldataPointer a, CalldataPointer b ) internal pure returns (bool c) { assembly { c := lt(a, b) } } function gt( CalldataPointer a, CalldataPointer b ) internal pure returns (bool c) { assembly { c := gt(a, b) } } function eq( CalldataPointer a, CalldataPointer b ) internal pure returns (bool c) { assembly { c := eq(a, b) } } function isNull(CalldataPointer a) internal pure returns (bool b) { assembly { b := iszero(a) } } /// @dev Resolves an offset stored at `cdPtr + headOffset` to a calldata. /// pointer `cdPtr` must point to some parent object with a dynamic /// type's head stored at `cdPtr + headOffset`. function pptr( CalldataPointer cdPtr, uint256 headOffset ) internal pure returns (CalldataPointer cdPtrChild) { cdPtrChild = cdPtr.offset( cdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask ); } /// @dev Resolves an offset stored at `cdPtr` to a calldata pointer. /// `cdPtr` must point to some parent object with a dynamic type as its /// first member, e.g. `struct { bytes data; }` function pptr( CalldataPointer cdPtr ) internal pure returns (CalldataPointer cdPtrChild) { cdPtrChild = cdPtr.offset(cdPtr.readUint256() & OffsetOrLengthMask); } /// @dev Returns the calldata pointer one word after `cdPtr`. function next( CalldataPointer cdPtr ) internal pure returns (CalldataPointer cdPtrNext) { assembly { cdPtrNext := add(cdPtr, _OneWord) } } /// @dev Returns the calldata pointer `_offset` bytes after `cdPtr`. function offset( CalldataPointer cdPtr, uint256 _offset ) internal pure returns (CalldataPointer cdPtrNext) { assembly { cdPtrNext := add(cdPtr, _offset) } } /// @dev Copies `size` bytes from calldata starting at `src` to memory at /// `dst`. function copy( CalldataPointer src, MemoryPointer dst, uint256 size ) internal pure { assembly { calldatacopy(dst, src, size) } } } library ReturndataPointerLib { function lt( ReturndataPointer a, ReturndataPointer b ) internal pure returns (bool c) { assembly { c := lt(a, b) } } function gt( ReturndataPointer a, ReturndataPointer b ) internal pure returns (bool c) { assembly { c := gt(a, b) } } function eq( ReturndataPointer a, ReturndataPointer b ) internal pure returns (bool c) { assembly { c := eq(a, b) } } function isNull(ReturndataPointer a) internal pure returns (bool b) { assembly { b := iszero(a) } } /// @dev Resolves an offset stored at `rdPtr + headOffset` to a returndata /// pointer. `rdPtr` must point to some parent object with a dynamic /// type's head stored at `rdPtr + headOffset`. function pptr( ReturndataPointer rdPtr, uint256 headOffset ) internal pure returns (ReturndataPointer rdPtrChild) { rdPtrChild = rdPtr.offset( rdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask ); } /// @dev Resolves an offset stored at `rdPtr` to a returndata pointer. /// `rdPtr` must point to some parent object with a dynamic type as its /// first member, e.g. `struct { bytes data; }` function pptr( ReturndataPointer rdPtr ) internal pure returns (ReturndataPointer rdPtrChild) { rdPtrChild = rdPtr.offset(rdPtr.readUint256() & OffsetOrLengthMask); } /// @dev Returns the returndata pointer one word after `cdPtr`. function next( ReturndataPointer rdPtr ) internal pure returns (ReturndataPointer rdPtrNext) { assembly { rdPtrNext := add(rdPtr, _OneWord) } } /// @dev Returns the returndata pointer `_offset` bytes after `cdPtr`. function offset( ReturndataPointer rdPtr, uint256 _offset ) internal pure returns (ReturndataPointer rdPtrNext) { assembly { rdPtrNext := add(rdPtr, _offset) } } /// @dev Copies `size` bytes from returndata starting at `src` to memory at /// `dst`. function copy( ReturndataPointer src, MemoryPointer dst, uint256 size ) internal pure { assembly { returndatacopy(dst, src, size) } } } library MemoryPointerLib { function copy( MemoryPointer src, MemoryPointer dst, uint256 size ) internal view { assembly { let success := staticcall( gas(), IdentityPrecompileAddress, src, size, dst, size ) if or(iszero(returndatasize()), iszero(success)) { revert(0, 0) } } } function lt( MemoryPointer a, MemoryPointer b ) internal pure returns (bool c) { assembly { c := lt(a, b) } } function gt( MemoryPointer a, MemoryPointer b ) internal pure returns (bool c) { assembly { c := gt(a, b) } } function eq( MemoryPointer a, MemoryPointer b ) internal pure returns (bool c) { assembly { c := eq(a, b) } } function isNull(MemoryPointer a) internal pure returns (bool b) { assembly { b := iszero(a) } } function hash( MemoryPointer ptr, uint256 length ) internal pure returns (bytes32 _hash) { assembly { _hash := keccak256(ptr, length) } } /// @dev Returns the memory pointer one word after `mPtr`. function next( MemoryPointer mPtr ) internal pure returns (MemoryPointer mPtrNext) { assembly { mPtrNext := add(mPtr, _OneWord) } } /// @dev Returns the memory pointer `_offset` bytes after `mPtr`. function offset( MemoryPointer mPtr, uint256 _offset ) internal pure returns (MemoryPointer mPtrNext) { assembly { mPtrNext := add(mPtr, _offset) } } /// @dev Resolves a pointer at `mPtr + headOffset` to a memory /// pointer. `mPtr` must point to some parent object with a dynamic /// type's pointer stored at `mPtr + headOffset`. function pptr( MemoryPointer mPtr, uint256 headOffset ) internal pure returns (MemoryPointer mPtrChild) { mPtrChild = mPtr.offset(headOffset).readMemoryPointer(); } /// @dev Resolves a pointer stored at `mPtr` to a memory pointer. /// `mPtr` must point to some parent object with a dynamic type as its /// first member, e.g. `struct { bytes data; }` function pptr( MemoryPointer mPtr ) internal pure returns (MemoryPointer mPtrChild) { mPtrChild = mPtr.readMemoryPointer(); } } library CalldataReaders { /// @dev Reads the value at `cdPtr` and applies a mask to return only the /// last 4 bytes. function readMaskedUint256( CalldataPointer cdPtr ) internal pure returns (uint256 value) { value = cdPtr.readUint256() & OffsetOrLengthMask; } /// @dev Reads the bool at `cdPtr` in calldata. function readBool( CalldataPointer cdPtr ) internal pure returns (bool value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the address at `cdPtr` in calldata. function readAddress( CalldataPointer cdPtr ) internal pure returns (address value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes1 at `cdPtr` in calldata. function readBytes1( CalldataPointer cdPtr ) internal pure returns (bytes1 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes2 at `cdPtr` in calldata. function readBytes2( CalldataPointer cdPtr ) internal pure returns (bytes2 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes3 at `cdPtr` in calldata. function readBytes3( CalldataPointer cdPtr ) internal pure returns (bytes3 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes4 at `cdPtr` in calldata. function readBytes4( CalldataPointer cdPtr ) internal pure returns (bytes4 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes5 at `cdPtr` in calldata. function readBytes5( CalldataPointer cdPtr ) internal pure returns (bytes5 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes6 at `cdPtr` in calldata. function readBytes6( CalldataPointer cdPtr ) internal pure returns (bytes6 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes7 at `cdPtr` in calldata. function readBytes7( CalldataPointer cdPtr ) internal pure returns (bytes7 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes8 at `cdPtr` in calldata. function readBytes8( CalldataPointer cdPtr ) internal pure returns (bytes8 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes9 at `cdPtr` in calldata. function readBytes9( CalldataPointer cdPtr ) internal pure returns (bytes9 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes10 at `cdPtr` in calldata. function readBytes10( CalldataPointer cdPtr ) internal pure returns (bytes10 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes11 at `cdPtr` in calldata. function readBytes11( CalldataPointer cdPtr ) internal pure returns (bytes11 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes12 at `cdPtr` in calldata. function readBytes12( CalldataPointer cdPtr ) internal pure returns (bytes12 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes13 at `cdPtr` in calldata. function readBytes13( CalldataPointer cdPtr ) internal pure returns (bytes13 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes14 at `cdPtr` in calldata. function readBytes14( CalldataPointer cdPtr ) internal pure returns (bytes14 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes15 at `cdPtr` in calldata. function readBytes15( CalldataPointer cdPtr ) internal pure returns (bytes15 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes16 at `cdPtr` in calldata. function readBytes16( CalldataPointer cdPtr ) internal pure returns (bytes16 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes17 at `cdPtr` in calldata. function readBytes17( CalldataPointer cdPtr ) internal pure returns (bytes17 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes18 at `cdPtr` in calldata. function readBytes18( CalldataPointer cdPtr ) internal pure returns (bytes18 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes19 at `cdPtr` in calldata. function readBytes19( CalldataPointer cdPtr ) internal pure returns (bytes19 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes20 at `cdPtr` in calldata. function readBytes20( CalldataPointer cdPtr ) internal pure returns (bytes20 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes21 at `cdPtr` in calldata. function readBytes21( CalldataPointer cdPtr ) internal pure returns (bytes21 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes22 at `cdPtr` in calldata. function readBytes22( CalldataPointer cdPtr ) internal pure returns (bytes22 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes23 at `cdPtr` in calldata. function readBytes23( CalldataPointer cdPtr ) internal pure returns (bytes23 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes24 at `cdPtr` in calldata. function readBytes24( CalldataPointer cdPtr ) internal pure returns (bytes24 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes25 at `cdPtr` in calldata. function readBytes25( CalldataPointer cdPtr ) internal pure returns (bytes25 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes26 at `cdPtr` in calldata. function readBytes26( CalldataPointer cdPtr ) internal pure returns (bytes26 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes27 at `cdPtr` in calldata. function readBytes27( CalldataPointer cdPtr ) internal pure returns (bytes27 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes28 at `cdPtr` in calldata. function readBytes28( CalldataPointer cdPtr ) internal pure returns (bytes28 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes29 at `cdPtr` in calldata. function readBytes29( CalldataPointer cdPtr ) internal pure returns (bytes29 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes30 at `cdPtr` in calldata. function readBytes30( CalldataPointer cdPtr ) internal pure returns (bytes30 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes31 at `cdPtr` in calldata. function readBytes31( CalldataPointer cdPtr ) internal pure returns (bytes31 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the bytes32 at `cdPtr` in calldata. function readBytes32( CalldataPointer cdPtr ) internal pure returns (bytes32 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint8 at `cdPtr` in calldata. function readUint8( CalldataPointer cdPtr ) internal pure returns (uint8 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint16 at `cdPtr` in calldata. function readUint16( CalldataPointer cdPtr ) internal pure returns (uint16 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint24 at `cdPtr` in calldata. function readUint24( CalldataPointer cdPtr ) internal pure returns (uint24 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint32 at `cdPtr` in calldata. function readUint32( CalldataPointer cdPtr ) internal pure returns (uint32 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint40 at `cdPtr` in calldata. function readUint40( CalldataPointer cdPtr ) internal pure returns (uint40 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint48 at `cdPtr` in calldata. function readUint48( CalldataPointer cdPtr ) internal pure returns (uint48 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint56 at `cdPtr` in calldata. function readUint56( CalldataPointer cdPtr ) internal pure returns (uint56 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint64 at `cdPtr` in calldata. function readUint64( CalldataPointer cdPtr ) internal pure returns (uint64 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint72 at `cdPtr` in calldata. function readUint72( CalldataPointer cdPtr ) internal pure returns (uint72 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint80 at `cdPtr` in calldata. function readUint80( CalldataPointer cdPtr ) internal pure returns (uint80 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint88 at `cdPtr` in calldata. function readUint88( CalldataPointer cdPtr ) internal pure returns (uint88 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint96 at `cdPtr` in calldata. function readUint96( CalldataPointer cdPtr ) internal pure returns (uint96 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint104 at `cdPtr` in calldata. function readUint104( CalldataPointer cdPtr ) internal pure returns (uint104 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint112 at `cdPtr` in calldata. function readUint112( CalldataPointer cdPtr ) internal pure returns (uint112 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint120 at `cdPtr` in calldata. function readUint120( CalldataPointer cdPtr ) internal pure returns (uint120 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint128 at `cdPtr` in calldata. function readUint128( CalldataPointer cdPtr ) internal pure returns (uint128 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint136 at `cdPtr` in calldata. function readUint136( CalldataPointer cdPtr ) internal pure returns (uint136 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint144 at `cdPtr` in calldata. function readUint144( CalldataPointer cdPtr ) internal pure returns (uint144 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint152 at `cdPtr` in calldata. function readUint152( CalldataPointer cdPtr ) internal pure returns (uint152 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint160 at `cdPtr` in calldata. function readUint160( CalldataPointer cdPtr ) internal pure returns (uint160 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint168 at `cdPtr` in calldata. function readUint168( CalldataPointer cdPtr ) internal pure returns (uint168 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint176 at `cdPtr` in calldata. function readUint176( CalldataPointer cdPtr ) internal pure returns (uint176 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint184 at `cdPtr` in calldata. function readUint184( CalldataPointer cdPtr ) internal pure returns (uint184 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint192 at `cdPtr` in calldata. function readUint192( CalldataPointer cdPtr ) internal pure returns (uint192 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint200 at `cdPtr` in calldata. function readUint200( CalldataPointer cdPtr ) internal pure returns (uint200 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint208 at `cdPtr` in calldata. function readUint208( CalldataPointer cdPtr ) internal pure returns (uint208 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint216 at `cdPtr` in calldata. function readUint216( CalldataPointer cdPtr ) internal pure returns (uint216 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint224 at `cdPtr` in calldata. function readUint224( CalldataPointer cdPtr ) internal pure returns (uint224 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint232 at `cdPtr` in calldata. function readUint232( CalldataPointer cdPtr ) internal pure returns (uint232 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint240 at `cdPtr` in calldata. function readUint240( CalldataPointer cdPtr ) internal pure returns (uint240 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint248 at `cdPtr` in calldata. function readUint248( CalldataPointer cdPtr ) internal pure returns (uint248 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the uint256 at `cdPtr` in calldata. function readUint256( CalldataPointer cdPtr ) internal pure returns (uint256 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int8 at `cdPtr` in calldata. function readInt8( CalldataPointer cdPtr ) internal pure returns (int8 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int16 at `cdPtr` in calldata. function readInt16( CalldataPointer cdPtr ) internal pure returns (int16 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int24 at `cdPtr` in calldata. function readInt24( CalldataPointer cdPtr ) internal pure returns (int24 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int32 at `cdPtr` in calldata. function readInt32( CalldataPointer cdPtr ) internal pure returns (int32 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int40 at `cdPtr` in calldata. function readInt40( CalldataPointer cdPtr ) internal pure returns (int40 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int48 at `cdPtr` in calldata. function readInt48( CalldataPointer cdPtr ) internal pure returns (int48 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int56 at `cdPtr` in calldata. function readInt56( CalldataPointer cdPtr ) internal pure returns (int56 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int64 at `cdPtr` in calldata. function readInt64( CalldataPointer cdPtr ) internal pure returns (int64 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int72 at `cdPtr` in calldata. function readInt72( CalldataPointer cdPtr ) internal pure returns (int72 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int80 at `cdPtr` in calldata. function readInt80( CalldataPointer cdPtr ) internal pure returns (int80 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int88 at `cdPtr` in calldata. function readInt88( CalldataPointer cdPtr ) internal pure returns (int88 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int96 at `cdPtr` in calldata. function readInt96( CalldataPointer cdPtr ) internal pure returns (int96 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int104 at `cdPtr` in calldata. function readInt104( CalldataPointer cdPtr ) internal pure returns (int104 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int112 at `cdPtr` in calldata. function readInt112( CalldataPointer cdPtr ) internal pure returns (int112 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int120 at `cdPtr` in calldata. function readInt120( CalldataPointer cdPtr ) internal pure returns (int120 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int128 at `cdPtr` in calldata. function readInt128( CalldataPointer cdPtr ) internal pure returns (int128 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int136 at `cdPtr` in calldata. function readInt136( CalldataPointer cdPtr ) internal pure returns (int136 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int144 at `cdPtr` in calldata. function readInt144( CalldataPointer cdPtr ) internal pure returns (int144 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int152 at `cdPtr` in calldata. function readInt152( CalldataPointer cdPtr ) internal pure returns (int152 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int160 at `cdPtr` in calldata. function readInt160( CalldataPointer cdPtr ) internal pure returns (int160 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int168 at `cdPtr` in calldata. function readInt168( CalldataPointer cdPtr ) internal pure returns (int168 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int176 at `cdPtr` in calldata. function readInt176( CalldataPointer cdPtr ) internal pure returns (int176 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int184 at `cdPtr` in calldata. function readInt184( CalldataPointer cdPtr ) internal pure returns (int184 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int192 at `cdPtr` in calldata. function readInt192( CalldataPointer cdPtr ) internal pure returns (int192 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int200 at `cdPtr` in calldata. function readInt200( CalldataPointer cdPtr ) internal pure returns (int200 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int208 at `cdPtr` in calldata. function readInt208( CalldataPointer cdPtr ) internal pure returns (int208 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int216 at `cdPtr` in calldata. function readInt216( CalldataPointer cdPtr ) internal pure returns (int216 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int224 at `cdPtr` in calldata. function readInt224( CalldataPointer cdPtr ) internal pure returns (int224 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int232 at `cdPtr` in calldata. function readInt232( CalldataPointer cdPtr ) internal pure returns (int232 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int240 at `cdPtr` in calldata. function readInt240( CalldataPointer cdPtr ) internal pure returns (int240 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int248 at `cdPtr` in calldata. function readInt248( CalldataPointer cdPtr ) internal pure returns (int248 value) { assembly { value := calldataload(cdPtr) } } /// @dev Reads the int256 at `cdPtr` in calldata. function readInt256( CalldataPointer cdPtr ) internal pure returns (int256 value) { assembly { value := calldataload(cdPtr) } } } library ReturndataReaders { /// @dev Reads value at `rdPtr` & applies a mask to return only last 4 bytes function readMaskedUint256( ReturndataPointer rdPtr ) internal pure returns (uint256 value) { value = rdPtr.readUint256() & OffsetOrLengthMask; } /// @dev Reads the bool at `rdPtr` in returndata. function readBool( ReturndataPointer rdPtr ) internal pure returns (bool value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the address at `rdPtr` in returndata. function readAddress( ReturndataPointer rdPtr ) internal pure returns (address value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes1 at `rdPtr` in returndata. function readBytes1( ReturndataPointer rdPtr ) internal pure returns (bytes1 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes2 at `rdPtr` in returndata. function readBytes2( ReturndataPointer rdPtr ) internal pure returns (bytes2 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes3 at `rdPtr` in returndata. function readBytes3( ReturndataPointer rdPtr ) internal pure returns (bytes3 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes4 at `rdPtr` in returndata. function readBytes4( ReturndataPointer rdPtr ) internal pure returns (bytes4 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes5 at `rdPtr` in returndata. function readBytes5( ReturndataPointer rdPtr ) internal pure returns (bytes5 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes6 at `rdPtr` in returndata. function readBytes6( ReturndataPointer rdPtr ) internal pure returns (bytes6 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes7 at `rdPtr` in returndata. function readBytes7( ReturndataPointer rdPtr ) internal pure returns (bytes7 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes8 at `rdPtr` in returndata. function readBytes8( ReturndataPointer rdPtr ) internal pure returns (bytes8 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes9 at `rdPtr` in returndata. function readBytes9( ReturndataPointer rdPtr ) internal pure returns (bytes9 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes10 at `rdPtr` in returndata. function readBytes10( ReturndataPointer rdPtr ) internal pure returns (bytes10 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes11 at `rdPtr` in returndata. function readBytes11( ReturndataPointer rdPtr ) internal pure returns (bytes11 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes12 at `rdPtr` in returndata. function readBytes12( ReturndataPointer rdPtr ) internal pure returns (bytes12 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes13 at `rdPtr` in returndata. function readBytes13( ReturndataPointer rdPtr ) internal pure returns (bytes13 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes14 at `rdPtr` in returndata. function readBytes14( ReturndataPointer rdPtr ) internal pure returns (bytes14 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes15 at `rdPtr` in returndata. function readBytes15( ReturndataPointer rdPtr ) internal pure returns (bytes15 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes16 at `rdPtr` in returndata. function readBytes16( ReturndataPointer rdPtr ) internal pure returns (bytes16 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes17 at `rdPtr` in returndata. function readBytes17( ReturndataPointer rdPtr ) internal pure returns (bytes17 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes18 at `rdPtr` in returndata. function readBytes18( ReturndataPointer rdPtr ) internal pure returns (bytes18 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes19 at `rdPtr` in returndata. function readBytes19( ReturndataPointer rdPtr ) internal pure returns (bytes19 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes20 at `rdPtr` in returndata. function readBytes20( ReturndataPointer rdPtr ) internal pure returns (bytes20 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes21 at `rdPtr` in returndata. function readBytes21( ReturndataPointer rdPtr ) internal pure returns (bytes21 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes22 at `rdPtr` in returndata. function readBytes22( ReturndataPointer rdPtr ) internal pure returns (bytes22 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes23 at `rdPtr` in returndata. function readBytes23( ReturndataPointer rdPtr ) internal pure returns (bytes23 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes24 at `rdPtr` in returndata. function readBytes24( ReturndataPointer rdPtr ) internal pure returns (bytes24 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes25 at `rdPtr` in returndata. function readBytes25( ReturndataPointer rdPtr ) internal pure returns (bytes25 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes26 at `rdPtr` in returndata. function readBytes26( ReturndataPointer rdPtr ) internal pure returns (bytes26 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes27 at `rdPtr` in returndata. function readBytes27( ReturndataPointer rdPtr ) internal pure returns (bytes27 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes28 at `rdPtr` in returndata. function readBytes28( ReturndataPointer rdPtr ) internal pure returns (bytes28 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes29 at `rdPtr` in returndata. function readBytes29( ReturndataPointer rdPtr ) internal pure returns (bytes29 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes30 at `rdPtr` in returndata. function readBytes30( ReturndataPointer rdPtr ) internal pure returns (bytes30 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes31 at `rdPtr` in returndata. function readBytes31( ReturndataPointer rdPtr ) internal pure returns (bytes31 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the bytes32 at `rdPtr` in returndata. function readBytes32( ReturndataPointer rdPtr ) internal pure returns (bytes32 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint8 at `rdPtr` in returndata. function readUint8( ReturndataPointer rdPtr ) internal pure returns (uint8 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint16 at `rdPtr` in returndata. function readUint16( ReturndataPointer rdPtr ) internal pure returns (uint16 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint24 at `rdPtr` in returndata. function readUint24( ReturndataPointer rdPtr ) internal pure returns (uint24 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint32 at `rdPtr` in returndata. function readUint32( ReturndataPointer rdPtr ) internal pure returns (uint32 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint40 at `rdPtr` in returndata. function readUint40( ReturndataPointer rdPtr ) internal pure returns (uint40 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint48 at `rdPtr` in returndata. function readUint48( ReturndataPointer rdPtr ) internal pure returns (uint48 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint56 at `rdPtr` in returndata. function readUint56( ReturndataPointer rdPtr ) internal pure returns (uint56 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint64 at `rdPtr` in returndata. function readUint64( ReturndataPointer rdPtr ) internal pure returns (uint64 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint72 at `rdPtr` in returndata. function readUint72( ReturndataPointer rdPtr ) internal pure returns (uint72 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint80 at `rdPtr` in returndata. function readUint80( ReturndataPointer rdPtr ) internal pure returns (uint80 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint88 at `rdPtr` in returndata. function readUint88( ReturndataPointer rdPtr ) internal pure returns (uint88 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint96 at `rdPtr` in returndata. function readUint96( ReturndataPointer rdPtr ) internal pure returns (uint96 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint104 at `rdPtr` in returndata. function readUint104( ReturndataPointer rdPtr ) internal pure returns (uint104 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint112 at `rdPtr` in returndata. function readUint112( ReturndataPointer rdPtr ) internal pure returns (uint112 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint120 at `rdPtr` in returndata. function readUint120( ReturndataPointer rdPtr ) internal pure returns (uint120 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint128 at `rdPtr` in returndata. function readUint128( ReturndataPointer rdPtr ) internal pure returns (uint128 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint136 at `rdPtr` in returndata. function readUint136( ReturndataPointer rdPtr ) internal pure returns (uint136 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint144 at `rdPtr` in returndata. function readUint144( ReturndataPointer rdPtr ) internal pure returns (uint144 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint152 at `rdPtr` in returndata. function readUint152( ReturndataPointer rdPtr ) internal pure returns (uint152 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint160 at `rdPtr` in returndata. function readUint160( ReturndataPointer rdPtr ) internal pure returns (uint160 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint168 at `rdPtr` in returndata. function readUint168( ReturndataPointer rdPtr ) internal pure returns (uint168 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint176 at `rdPtr` in returndata. function readUint176( ReturndataPointer rdPtr ) internal pure returns (uint176 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint184 at `rdPtr` in returndata. function readUint184( ReturndataPointer rdPtr ) internal pure returns (uint184 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint192 at `rdPtr` in returndata. function readUint192( ReturndataPointer rdPtr ) internal pure returns (uint192 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint200 at `rdPtr` in returndata. function readUint200( ReturndataPointer rdPtr ) internal pure returns (uint200 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint208 at `rdPtr` in returndata. function readUint208( ReturndataPointer rdPtr ) internal pure returns (uint208 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint216 at `rdPtr` in returndata. function readUint216( ReturndataPointer rdPtr ) internal pure returns (uint216 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint224 at `rdPtr` in returndata. function readUint224( ReturndataPointer rdPtr ) internal pure returns (uint224 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint232 at `rdPtr` in returndata. function readUint232( ReturndataPointer rdPtr ) internal pure returns (uint232 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint240 at `rdPtr` in returndata. function readUint240( ReturndataPointer rdPtr ) internal pure returns (uint240 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint248 at `rdPtr` in returndata. function readUint248( ReturndataPointer rdPtr ) internal pure returns (uint248 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the uint256 at `rdPtr` in returndata. function readUint256( ReturndataPointer rdPtr ) internal pure returns (uint256 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int8 at `rdPtr` in returndata. function readInt8( ReturndataPointer rdPtr ) internal pure returns (int8 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int16 at `rdPtr` in returndata. function readInt16( ReturndataPointer rdPtr ) internal pure returns (int16 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int24 at `rdPtr` in returndata. function readInt24( ReturndataPointer rdPtr ) internal pure returns (int24 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int32 at `rdPtr` in returndata. function readInt32( ReturndataPointer rdPtr ) internal pure returns (int32 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int40 at `rdPtr` in returndata. function readInt40( ReturndataPointer rdPtr ) internal pure returns (int40 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int48 at `rdPtr` in returndata. function readInt48( ReturndataPointer rdPtr ) internal pure returns (int48 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int56 at `rdPtr` in returndata. function readInt56( ReturndataPointer rdPtr ) internal pure returns (int56 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int64 at `rdPtr` in returndata. function readInt64( ReturndataPointer rdPtr ) internal pure returns (int64 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int72 at `rdPtr` in returndata. function readInt72( ReturndataPointer rdPtr ) internal pure returns (int72 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int80 at `rdPtr` in returndata. function readInt80( ReturndataPointer rdPtr ) internal pure returns (int80 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int88 at `rdPtr` in returndata. function readInt88( ReturndataPointer rdPtr ) internal pure returns (int88 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int96 at `rdPtr` in returndata. function readInt96( ReturndataPointer rdPtr ) internal pure returns (int96 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int104 at `rdPtr` in returndata. function readInt104( ReturndataPointer rdPtr ) internal pure returns (int104 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int112 at `rdPtr` in returndata. function readInt112( ReturndataPointer rdPtr ) internal pure returns (int112 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int120 at `rdPtr` in returndata. function readInt120( ReturndataPointer rdPtr ) internal pure returns (int120 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int128 at `rdPtr` in returndata. function readInt128( ReturndataPointer rdPtr ) internal pure returns (int128 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int136 at `rdPtr` in returndata. function readInt136( ReturndataPointer rdPtr ) internal pure returns (int136 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int144 at `rdPtr` in returndata. function readInt144( ReturndataPointer rdPtr ) internal pure returns (int144 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int152 at `rdPtr` in returndata. function readInt152( ReturndataPointer rdPtr ) internal pure returns (int152 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int160 at `rdPtr` in returndata. function readInt160( ReturndataPointer rdPtr ) internal pure returns (int160 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int168 at `rdPtr` in returndata. function readInt168( ReturndataPointer rdPtr ) internal pure returns (int168 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int176 at `rdPtr` in returndata. function readInt176( ReturndataPointer rdPtr ) internal pure returns (int176 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int184 at `rdPtr` in returndata. function readInt184( ReturndataPointer rdPtr ) internal pure returns (int184 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int192 at `rdPtr` in returndata. function readInt192( ReturndataPointer rdPtr ) internal pure returns (int192 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int200 at `rdPtr` in returndata. function readInt200( ReturndataPointer rdPtr ) internal pure returns (int200 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int208 at `rdPtr` in returndata. function readInt208( ReturndataPointer rdPtr ) internal pure returns (int208 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int216 at `rdPtr` in returndata. function readInt216( ReturndataPointer rdPtr ) internal pure returns (int216 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int224 at `rdPtr` in returndata. function readInt224( ReturndataPointer rdPtr ) internal pure returns (int224 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int232 at `rdPtr` in returndata. function readInt232( ReturndataPointer rdPtr ) internal pure returns (int232 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int240 at `rdPtr` in returndata. function readInt240( ReturndataPointer rdPtr ) internal pure returns (int240 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int248 at `rdPtr` in returndata. function readInt248( ReturndataPointer rdPtr ) internal pure returns (int248 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } /// @dev Reads the int256 at `rdPtr` in returndata. function readInt256( ReturndataPointer rdPtr ) internal pure returns (int256 value) { assembly { returndatacopy(0, rdPtr, _OneWord) value := mload(0) } } } library MemoryReaders { /// @dev Reads the memory pointer at `mPtr` in memory. function readMemoryPointer( MemoryPointer mPtr ) internal pure returns (MemoryPointer value) { assembly { value := mload(mPtr) } } /// @dev Reads value at `mPtr` & applies a mask to return only last 4 bytes function readMaskedUint256( MemoryPointer mPtr ) internal pure returns (uint256 value) { value = mPtr.readUint256() & OffsetOrLengthMask; } /// @dev Reads the bool at `mPtr` in memory. function readBool(MemoryPointer mPtr) internal pure returns (bool value) { assembly { value := mload(mPtr) } } /// @dev Reads the address at `mPtr` in memory. function readAddress( MemoryPointer mPtr ) internal pure returns (address value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes1 at `mPtr` in memory. function readBytes1( MemoryPointer mPtr ) internal pure returns (bytes1 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes2 at `mPtr` in memory. function readBytes2( MemoryPointer mPtr ) internal pure returns (bytes2 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes3 at `mPtr` in memory. function readBytes3( MemoryPointer mPtr ) internal pure returns (bytes3 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes4 at `mPtr` in memory. function readBytes4( MemoryPointer mPtr ) internal pure returns (bytes4 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes5 at `mPtr` in memory. function readBytes5( MemoryPointer mPtr ) internal pure returns (bytes5 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes6 at `mPtr` in memory. function readBytes6( MemoryPointer mPtr ) internal pure returns (bytes6 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes7 at `mPtr` in memory. function readBytes7( MemoryPointer mPtr ) internal pure returns (bytes7 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes8 at `mPtr` in memory. function readBytes8( MemoryPointer mPtr ) internal pure returns (bytes8 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes9 at `mPtr` in memory. function readBytes9( MemoryPointer mPtr ) internal pure returns (bytes9 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes10 at `mPtr` in memory. function readBytes10( MemoryPointer mPtr ) internal pure returns (bytes10 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes11 at `mPtr` in memory. function readBytes11( MemoryPointer mPtr ) internal pure returns (bytes11 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes12 at `mPtr` in memory. function readBytes12( MemoryPointer mPtr ) internal pure returns (bytes12 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes13 at `mPtr` in memory. function readBytes13( MemoryPointer mPtr ) internal pure returns (bytes13 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes14 at `mPtr` in memory. function readBytes14( MemoryPointer mPtr ) internal pure returns (bytes14 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes15 at `mPtr` in memory. function readBytes15( MemoryPointer mPtr ) internal pure returns (bytes15 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes16 at `mPtr` in memory. function readBytes16( MemoryPointer mPtr ) internal pure returns (bytes16 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes17 at `mPtr` in memory. function readBytes17( MemoryPointer mPtr ) internal pure returns (bytes17 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes18 at `mPtr` in memory. function readBytes18( MemoryPointer mPtr ) internal pure returns (bytes18 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes19 at `mPtr` in memory. function readBytes19( MemoryPointer mPtr ) internal pure returns (bytes19 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes20 at `mPtr` in memory. function readBytes20( MemoryPointer mPtr ) internal pure returns (bytes20 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes21 at `mPtr` in memory. function readBytes21( MemoryPointer mPtr ) internal pure returns (bytes21 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes22 at `mPtr` in memory. function readBytes22( MemoryPointer mPtr ) internal pure returns (bytes22 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes23 at `mPtr` in memory. function readBytes23( MemoryPointer mPtr ) internal pure returns (bytes23 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes24 at `mPtr` in memory. function readBytes24( MemoryPointer mPtr ) internal pure returns (bytes24 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes25 at `mPtr` in memory. function readBytes25( MemoryPointer mPtr ) internal pure returns (bytes25 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes26 at `mPtr` in memory. function readBytes26( MemoryPointer mPtr ) internal pure returns (bytes26 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes27 at `mPtr` in memory. function readBytes27( MemoryPointer mPtr ) internal pure returns (bytes27 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes28 at `mPtr` in memory. function readBytes28( MemoryPointer mPtr ) internal pure returns (bytes28 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes29 at `mPtr` in memory. function readBytes29( MemoryPointer mPtr ) internal pure returns (bytes29 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes30 at `mPtr` in memory. function readBytes30( MemoryPointer mPtr ) internal pure returns (bytes30 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes31 at `mPtr` in memory. function readBytes31( MemoryPointer mPtr ) internal pure returns (bytes31 value) { assembly { value := mload(mPtr) } } /// @dev Reads the bytes32 at `mPtr` in memory. function readBytes32( MemoryPointer mPtr ) internal pure returns (bytes32 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint8 at `mPtr` in memory. function readUint8(MemoryPointer mPtr) internal pure returns (uint8 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint16 at `mPtr` in memory. function readUint16( MemoryPointer mPtr ) internal pure returns (uint16 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint24 at `mPtr` in memory. function readUint24( MemoryPointer mPtr ) internal pure returns (uint24 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint32 at `mPtr` in memory. function readUint32( MemoryPointer mPtr ) internal pure returns (uint32 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint40 at `mPtr` in memory. function readUint40( MemoryPointer mPtr ) internal pure returns (uint40 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint48 at `mPtr` in memory. function readUint48( MemoryPointer mPtr ) internal pure returns (uint48 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint56 at `mPtr` in memory. function readUint56( MemoryPointer mPtr ) internal pure returns (uint56 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint64 at `mPtr` in memory. function readUint64( MemoryPointer mPtr ) internal pure returns (uint64 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint72 at `mPtr` in memory. function readUint72( MemoryPointer mPtr ) internal pure returns (uint72 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint80 at `mPtr` in memory. function readUint80( MemoryPointer mPtr ) internal pure returns (uint80 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint88 at `mPtr` in memory. function readUint88( MemoryPointer mPtr ) internal pure returns (uint88 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint96 at `mPtr` in memory. function readUint96( MemoryPointer mPtr ) internal pure returns (uint96 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint104 at `mPtr` in memory. function readUint104( MemoryPointer mPtr ) internal pure returns (uint104 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint112 at `mPtr` in memory. function readUint112( MemoryPointer mPtr ) internal pure returns (uint112 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint120 at `mPtr` in memory. function readUint120( MemoryPointer mPtr ) internal pure returns (uint120 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint128 at `mPtr` in memory. function readUint128( MemoryPointer mPtr ) internal pure returns (uint128 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint136 at `mPtr` in memory. function readUint136( MemoryPointer mPtr ) internal pure returns (uint136 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint144 at `mPtr` in memory. function readUint144( MemoryPointer mPtr ) internal pure returns (uint144 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint152 at `mPtr` in memory. function readUint152( MemoryPointer mPtr ) internal pure returns (uint152 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint160 at `mPtr` in memory. function readUint160( MemoryPointer mPtr ) internal pure returns (uint160 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint168 at `mPtr` in memory. function readUint168( MemoryPointer mPtr ) internal pure returns (uint168 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint176 at `mPtr` in memory. function readUint176( MemoryPointer mPtr ) internal pure returns (uint176 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint184 at `mPtr` in memory. function readUint184( MemoryPointer mPtr ) internal pure returns (uint184 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint192 at `mPtr` in memory. function readUint192( MemoryPointer mPtr ) internal pure returns (uint192 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint200 at `mPtr` in memory. function readUint200( MemoryPointer mPtr ) internal pure returns (uint200 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint208 at `mPtr` in memory. function readUint208( MemoryPointer mPtr ) internal pure returns (uint208 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint216 at `mPtr` in memory. function readUint216( MemoryPointer mPtr ) internal pure returns (uint216 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint224 at `mPtr` in memory. function readUint224( MemoryPointer mPtr ) internal pure returns (uint224 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint232 at `mPtr` in memory. function readUint232( MemoryPointer mPtr ) internal pure returns (uint232 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint240 at `mPtr` in memory. function readUint240( MemoryPointer mPtr ) internal pure returns (uint240 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint248 at `mPtr` in memory. function readUint248( MemoryPointer mPtr ) internal pure returns (uint248 value) { assembly { value := mload(mPtr) } } /// @dev Reads the uint256 at `mPtr` in memory. function readUint256( MemoryPointer mPtr ) internal pure returns (uint256 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int8 at `mPtr` in memory. function readInt8(MemoryPointer mPtr) internal pure returns (int8 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int16 at `mPtr` in memory. function readInt16(MemoryPointer mPtr) internal pure returns (int16 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int24 at `mPtr` in memory. function readInt24(MemoryPointer mPtr) internal pure returns (int24 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int32 at `mPtr` in memory. function readInt32(MemoryPointer mPtr) internal pure returns (int32 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int40 at `mPtr` in memory. function readInt40(MemoryPointer mPtr) internal pure returns (int40 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int48 at `mPtr` in memory. function readInt48(MemoryPointer mPtr) internal pure returns (int48 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int56 at `mPtr` in memory. function readInt56(MemoryPointer mPtr) internal pure returns (int56 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int64 at `mPtr` in memory. function readInt64(MemoryPointer mPtr) internal pure returns (int64 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int72 at `mPtr` in memory. function readInt72(MemoryPointer mPtr) internal pure returns (int72 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int80 at `mPtr` in memory. function readInt80(MemoryPointer mPtr) internal pure returns (int80 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int88 at `mPtr` in memory. function readInt88(MemoryPointer mPtr) internal pure returns (int88 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int96 at `mPtr` in memory. function readInt96(MemoryPointer mPtr) internal pure returns (int96 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int104 at `mPtr` in memory. function readInt104( MemoryPointer mPtr ) internal pure returns (int104 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int112 at `mPtr` in memory. function readInt112( MemoryPointer mPtr ) internal pure returns (int112 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int120 at `mPtr` in memory. function readInt120( MemoryPointer mPtr ) internal pure returns (int120 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int128 at `mPtr` in memory. function readInt128( MemoryPointer mPtr ) internal pure returns (int128 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int136 at `mPtr` in memory. function readInt136( MemoryPointer mPtr ) internal pure returns (int136 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int144 at `mPtr` in memory. function readInt144( MemoryPointer mPtr ) internal pure returns (int144 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int152 at `mPtr` in memory. function readInt152( MemoryPointer mPtr ) internal pure returns (int152 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int160 at `mPtr` in memory. function readInt160( MemoryPointer mPtr ) internal pure returns (int160 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int168 at `mPtr` in memory. function readInt168( MemoryPointer mPtr ) internal pure returns (int168 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int176 at `mPtr` in memory. function readInt176( MemoryPointer mPtr ) internal pure returns (int176 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int184 at `mPtr` in memory. function readInt184( MemoryPointer mPtr ) internal pure returns (int184 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int192 at `mPtr` in memory. function readInt192( MemoryPointer mPtr ) internal pure returns (int192 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int200 at `mPtr` in memory. function readInt200( MemoryPointer mPtr ) internal pure returns (int200 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int208 at `mPtr` in memory. function readInt208( MemoryPointer mPtr ) internal pure returns (int208 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int216 at `mPtr` in memory. function readInt216( MemoryPointer mPtr ) internal pure returns (int216 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int224 at `mPtr` in memory. function readInt224( MemoryPointer mPtr ) internal pure returns (int224 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int232 at `mPtr` in memory. function readInt232( MemoryPointer mPtr ) internal pure returns (int232 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int240 at `mPtr` in memory. function readInt240( MemoryPointer mPtr ) internal pure returns (int240 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int248 at `mPtr` in memory. function readInt248( MemoryPointer mPtr ) internal pure returns (int248 value) { assembly { value := mload(mPtr) } } /// @dev Reads the int256 at `mPtr` in memory. function readInt256( MemoryPointer mPtr ) internal pure returns (int256 value) { assembly { value := mload(mPtr) } } } library MemoryWriters { /// @dev Writes `valuePtr` to memory at `mPtr`. function write(MemoryPointer mPtr, MemoryPointer valuePtr) internal pure { assembly { mstore(mPtr, valuePtr) } } /// @dev Writes a boolean `value` to `mPtr` in memory. function write(MemoryPointer mPtr, bool value) internal pure { assembly { mstore(mPtr, value) } } /// @dev Writes an address `value` to `mPtr` in memory. function write(MemoryPointer mPtr, address value) internal pure { assembly { mstore(mPtr, value) } } /// @dev Writes a bytes32 `value` to `mPtr` in memory. /// Separate name to disambiguate literal write parameters. function writeBytes32(MemoryPointer mPtr, bytes32 value) internal pure { assembly { mstore(mPtr, value) } } /// @dev Writes a uint256 `value` to `mPtr` in memory. function write(MemoryPointer mPtr, uint256 value) internal pure { assembly { mstore(mPtr, value) } } /// @dev Writes an int256 `value` to `mPtr` in memory. /// Separate name to disambiguate literal write parameters. function writeInt(MemoryPointer mPtr, int256 value) internal pure { assembly { mstore(mPtr, value) } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) abstract contract Auth { event OwnershipTransferred(address indexed user, address indexed newOwner); event AuthorityUpdated(address indexed user, Authority indexed newAuthority); address public owner; Authority public authority; constructor(address _owner, Authority _authority) { owner = _owner; authority = _authority; emit OwnershipTransferred(msg.sender, _owner); emit AuthorityUpdated(msg.sender, _authority); } modifier requiresAuth() virtual { require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED"); _; } function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) { Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas. // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be // aware that this makes protected functions uncallable even to the owner if the authority is out of order. return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner; } function setAuthority(Authority newAuthority) public virtual { // We check if the caller is the owner first because we want to ensure they can // always swap out the authority even if it's reverting or using up a lot of gas. require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig)); authority = newAuthority; emit AuthorityUpdated(msg.sender, newAuthority); } function transferOwnership(address newOwner) public virtual requiresAuth { owner = newOwner; emit OwnershipTransferred(msg.sender, newOwner); } } /// @notice A generic interface for a contract which provides authorization data to an Auth instance. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) interface Authority { function canCall( address user, address target, bytes4 functionSig ) external view returns (bool); }
// SPDX-License-Identifier: BUSL-1.1 /** * █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗ █████╗ * ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║██╔══██╗ * ███████║███████╗ ██║ ███████║██████╔╝██║███████║ * ██╔══██║╚════██║ ██║ ██╔══██║██╔══██╗██║██╔══██║ * ██║ ██║███████║ ██║ ██║ ██║██║ ██║██║██║ ██║ * ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ * * Astaria Labs, Inc */ pragma solidity =0.8.17; import {Authority} from "solmate/auth/Auth.sol"; /// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic. /// @author Astaria (https://github.com/astariaxyz/astaria-gpl/blob/main/src/auth/AuthInitializable.sol) /// @author Modified from (https://github.com/transmissions11/solmate/v7/main/src/auth/Auth.sol) abstract contract AuthInitializable { event OwnershipTransferred(address indexed user, address indexed newOwner); event AuthorityUpdated(address indexed user, Authority indexed newAuthority); uint256 private constant authSlot = uint256(uint256(keccak256("xyz.astaria.Auth.storage.location")) - 1); struct AuthStorage { address owner; Authority authority; } function _getAuthSlot() internal view returns (AuthStorage storage s) { uint256 slot = authSlot; assembly { s.slot := slot } } function __initAuth(address _owner, address _authority) internal { AuthStorage storage s = _getAuthSlot(); require(s.owner == address(0), "Already initialized"); s.owner = _owner; s.authority = Authority(_authority); emit OwnershipTransferred(msg.sender, _owner); emit AuthorityUpdated(msg.sender, Authority(_authority)); } modifier requiresAuth() virtual { require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED"); _; } function owner() public view returns (address) { return _getAuthSlot().owner; } function authority() public view returns (Authority) { return _getAuthSlot().authority; } function isAuthorized( address user, bytes4 functionSig ) internal view virtual returns (bool) { AuthStorage storage s = _getAuthSlot(); Authority auth = s.authority; // Memoizing authority saves us a warm SLOAD, around 100 gas. // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be // aware that this makes protected functions uncallable even to the owner if the authority is out of order. return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == s.owner; } function setAuthority(Authority newAuthority) public virtual { // We check if the caller is the owner first because we want to ensure they can // always swap out the authority even if it's reverting or using up a lot of gas. AuthStorage storage s = _getAuthSlot(); require( msg.sender == s.owner || s.authority.canCall(msg.sender, address(this), msg.sig) ); s.authority = newAuthority; emit AuthorityUpdated(msg.sender, newAuthority); } function transferOwnership(address newOwner) public virtual requiresAuth { AuthStorage storage s = _getAuthSlot(); s.owner = newOwner; emit OwnershipTransferred(msg.sender, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require( success, "Address: unable to send value, recipient may have reverted" ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, "Address: low-level call with value failed" ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, "Address: insufficient balance for call" ); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data ) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data ) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert( bytes memory returndata, string memory errorMessage ) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { uint256 private constant INITIALIZER_SLOT = uint256( uint256(keccak256("core.astaria.xyz.initializer.storage.location")) - 1 ); struct InitializerState { uint8 _initialized; bool _initializing; } /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); function _getInitializerSlot() private view returns (InitializerState storage state) { uint256 slot = INITIALIZER_SLOT; assembly { state.slot := slot } } /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { InitializerState storage s = _getInitializerSlot(); bool isTopLevelCall = !s._initializing; require( (isTopLevelCall && s._initialized < 1) || (!Address.isContract(address(this)) && s._initialized == 1), "Initializable: contract is already initialized" ); s._initialized = 1; if (isTopLevelCall) { s._initializing = true; } _; if (isTopLevelCall) { s._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { InitializerState storage s = _getInitializerSlot(); require( !s._initializing && s._initialized < version, "Initializable: contract is already initialized" ); s._initialized = version; s._initializing = true; _; s._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { InitializerState storage s = _getInitializerSlot(); require(s._initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { InitializerState storage s = _getInitializerSlot(); require(!s._initializing, "Initializable: contract is initializing"); if (s._initialized < type(uint8).max) { s._initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {AmountDerivationErrors} from "seaport-types/src/interfaces/AmountDerivationErrors.sol"; import { Error_selector_offset, InexactFraction_error_length, InexactFraction_error_selector } from "seaport-types/src/lib/ConsiderationErrorConstants.sol"; /** * @title AmountDeriver * @author 0age * @notice AmountDeriver contains view and pure functions related to deriving * item amounts based on partial fill quantity and on linear * interpolation based on current time when the start amount and end * amount differ. */ contract AmountDeriver is AmountDerivationErrors { /** * @dev Internal view function to derive the current amount of a given item * based on the current price, the starting price, and the ending * price. If the start and end prices differ, the current price will be * interpolated on a linear basis. Note that this function expects that * the startTime parameter of orderParameters is not greater than the * current block timestamp and that the endTime parameter is greater * than the current block timestamp. If this condition is not upheld, * duration / elapsed / remaining variables will underflow. * * @param startAmount The starting amount of the item. * @param endAmount The ending amount of the item. * @param startTime The starting time of the order. * @param endTime The end time of the order. * @param roundUp A boolean indicating whether the resultant amount * should be rounded up or down. * * @return amount The current amount. */ function _locateCurrentAmount( uint256 startAmount, uint256 endAmount, uint256 startTime, uint256 endTime, bool roundUp ) internal view returns (uint256 amount) { // Only modify end amount if it doesn't already equal start amount. if (startAmount != endAmount) { // Declare variables to derive in the subsequent unchecked scope. uint256 duration; uint256 elapsed; uint256 remaining; // Skip underflow checks as startTime <= block.timestamp < endTime. unchecked { // Derive the duration for the order and place it on the stack. duration = endTime - startTime; // Derive time elapsed since the order started & place on stack. elapsed = block.timestamp - startTime; // Derive time remaining until order expires and place on stack. remaining = duration - elapsed; } // Aggregate new amounts weighted by time with rounding factor. uint256 totalBeforeDivision = ((startAmount * remaining) + (endAmount * elapsed)); // Use assembly to combine operations and skip divide-by-zero check. assembly { // Multiply by iszero(iszero(totalBeforeDivision)) to ensure // amount is set to zero if totalBeforeDivision is zero, // as intermediate overflow can occur if it is zero. amount := mul( iszero(iszero(totalBeforeDivision)), // Subtract 1 from the numerator and add 1 to the result if // roundUp is true to get the proper rounding direction. // Division is performed with no zero check as duration // cannot be zero as long as startTime < endTime. add(div(sub(totalBeforeDivision, roundUp), duration), roundUp) ) } // Return the current amount. return amount; } // Return the original amount as startAmount == endAmount. return endAmount; } /** * @dev Internal pure function to return a fraction of a given value and to * ensure the resultant value does not have any fractional component. * Note that this function assumes that zero will never be supplied as * the denominator parameter; invalid / undefined behavior will result * should a denominator of zero be provided. * * @param numerator A value indicating the portion of the order that * should be filled. * @param denominator A value indicating the total size of the order. Note * that this value cannot be equal to zero. * @param value The value for which to compute the fraction. * * @return newValue The value after applying the fraction. */ function _getFraction(uint256 numerator, uint256 denominator, uint256 value) internal pure returns (uint256 newValue) { // Return value early in cases where the fraction resolves to 1. if (numerator == denominator) { return value; } // Ensure fraction can be applied to the value with no remainder. Note // that the denominator cannot be zero. assembly { // Ensure new value contains no remainder via mulmod operator. // Credit to @hrkrshnn + @axic for proposing this optimal solution. if mulmod(value, numerator, denominator) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InexactFraction_error_selector) // revert(abi.encodeWithSignature("InexactFraction()")) revert(Error_selector_offset, InexactFraction_error_length) } } // Multiply the numerator by the value and ensure no overflow occurs. uint256 valueTimesNumerator = value * numerator; // Divide and check for remainder. Note that denominator cannot be zero. assembly { // Perform division without zero check. newValue := div(valueTimesNumerator, denominator) } } /** * @dev Internal view function to apply a fraction to a consideration * or offer item. * * @param startAmount The starting amount of the item. * @param endAmount The ending amount of the item. * @param numerator A value indicating the portion of the order that * should be filled. * @param denominator A value indicating the total size of the order. * @param startTime The starting time of the order. * @param endTime The end time of the order. * @param roundUp A boolean indicating whether the resultant * amount should be rounded up or down. * * @return amount The received item to transfer with the final amount. */ function _applyFraction( uint256 startAmount, uint256 endAmount, uint256 numerator, uint256 denominator, uint256 startTime, uint256 endTime, bool roundUp ) internal view returns (uint256 amount) { // If start amount equals end amount, apply fraction to end amount. if (startAmount == endAmount) { // Apply fraction to end amount. amount = _getFraction(numerator, denominator, endAmount); } else { // Otherwise, apply fraction to both and interpolated final amount. amount = _locateCurrentAmount( _getFraction(numerator, denominator, startAmount), _getFraction(numerator, denominator, endAmount), startTime, endTime, roundUp ); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title AmountDerivationErrors * @author 0age * @notice AmountDerivationErrors contains errors related to amount derivation. */ interface AmountDerivationErrors { /** * @dev Revert with an error when attempting to apply a fraction as part of * a partial fill that does not divide the target amount cleanly. */ error InexactFraction(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; uint256 constant Error_selector_offset = 0x1c; /* * error MissingFulfillmentComponentOnAggregation(uint8 side) * - Defined in FulfillmentApplicationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: side * Revert buffer is memory[0x1c:0x40] */ uint256 constant MissingFulfillmentComponentOnAggregation_error_selector = ( 0x375c24c1 ); uint256 constant MissingFulfillmentComponentOnAggregation_error_side_ptr = 0x20; uint256 constant MissingFulfillmentComponentOnAggregation_error_length = 0x24; /* * error OfferAndConsiderationRequiredOnFulfillment() * - Defined in FulfillmentApplicationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant OfferAndConsiderationRequiredOnFulfillment_error_selector = ( 0x98e9db6e ); uint256 constant OfferAndConsiderationRequiredOnFulfillment_error_length = 0x04; /* * error MismatchedFulfillmentOfferAndConsiderationComponents( * uint256 fulfillmentIndex * ) * - Defined in FulfillmentApplicationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: fulfillmentIndex * Revert buffer is memory[0x1c:0x40] */ uint256 constant MismatchedOfferAndConsiderationComponents_error_selector = ( 0xbced929d ); uint256 constant MismatchedOfferAndConsiderationComponents_error_idx_ptr = 0x20; uint256 constant MismatchedOfferAndConsiderationComponents_error_length = 0x24; /* * error InvalidFulfillmentComponentData() * - Defined in FulfillmentApplicationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InvalidFulfillmentComponentData_error_selector = 0x7fda7279; uint256 constant InvalidFulfillmentComponentData_error_length = 0x04; /* * error InexactFraction() * - Defined in AmountDerivationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InexactFraction_error_selector = 0xc63cf089; uint256 constant InexactFraction_error_length = 0x04; /* * error OrderCriteriaResolverOutOfRange(uint8 side) * - Defined in CriteriaResolutionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: side * Revert buffer is memory[0x1c:0x40] */ uint256 constant OrderCriteriaResolverOutOfRange_error_selector = 0x133c37c6; uint256 constant OrderCriteriaResolverOutOfRange_error_side_ptr = 0x20; uint256 constant OrderCriteriaResolverOutOfRange_error_length = 0x24; /* * error UnresolvedOfferCriteria(uint256 orderIndex, uint256 offerIndex) * - Defined in CriteriaResolutionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderIndex * - 0x40: offerIndex * Revert buffer is memory[0x1c:0x60] */ uint256 constant UnresolvedOfferCriteria_error_selector = 0xd6929332; uint256 constant UnresolvedOfferCriteria_error_orderIndex_ptr = 0x20; uint256 constant UnresolvedOfferCriteria_error_offerIndex_ptr = 0x40; uint256 constant UnresolvedOfferCriteria_error_length = 0x44; /* * error UnresolvedConsiderationCriteria( * uint256 orderIndex, * uint256 considerationIndex * ) * - Defined in CriteriaResolutionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderIndex * - 0x40: considerationIndex * Revert buffer is memory[0x1c:0x60] */ uint256 constant UnresolvedConsiderationCriteria_error_selector = 0xa8930e9a; uint256 constant UnresolvedConsiderationCriteria_error_orderIndex_ptr = 0x20; uint256 constant UnresolvedConsiderationCriteria_error_considerationIdx_ptr = ( 0x40 ); uint256 constant UnresolvedConsiderationCriteria_error_length = 0x44; /* * error OfferCriteriaResolverOutOfRange() * - Defined in CriteriaResolutionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant OfferCriteriaResolverOutOfRange_error_selector = 0xbfb3f8ce; // uint256 constant OfferCriteriaResolverOutOfRange_error_length = 0x04; /* * error ConsiderationCriteriaResolverOutOfRange() * - Defined in CriteriaResolutionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant ConsiderationCriteriaResolverOutOfRange_error_selector = ( 0x6088d7de ); uint256 constant ConsiderationCriteriaResolverOutOfRange_err_selector = ( 0x6088d7de ); // uint256 constant ConsiderationCriteriaResolverOutOfRange_error_length = 0x04; /* * error CriteriaNotEnabledForItem() * - Defined in CriteriaResolutionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant CriteriaNotEnabledForItem_error_selector = 0x94eb6af6; uint256 constant CriteriaNotEnabledForItem_error_length = 0x04; /* * error InvalidProof() * - Defined in CriteriaResolutionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InvalidProof_error_selector = 0x09bde339; uint256 constant InvalidProof_error_length = 0x04; /* * error InvalidRestrictedOrder(bytes32 orderHash) * - Defined in ZoneInteractionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderHash * Revert buffer is memory[0x1c:0x40] */ uint256 constant InvalidRestrictedOrder_error_selector = 0xfb5014fc; uint256 constant InvalidRestrictedOrder_error_orderHash_ptr = 0x20; uint256 constant InvalidRestrictedOrder_error_length = 0x24; /* * error InvalidContractOrder(bytes32 orderHash) * - Defined in ZoneInteractionErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderHash * Revert buffer is memory[0x1c:0x40] */ uint256 constant InvalidContractOrder_error_selector = 0x93979285; uint256 constant InvalidContractOrder_error_orderHash_ptr = 0x20; uint256 constant InvalidContractOrder_error_length = 0x24; /* * error BadSignatureV(uint8 v) * - Defined in SignatureVerificationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: v * Revert buffer is memory[0x1c:0x40] */ uint256 constant BadSignatureV_error_selector = 0x1f003d0a; uint256 constant BadSignatureV_error_v_ptr = 0x20; uint256 constant BadSignatureV_error_length = 0x24; /* * error InvalidSigner() * - Defined in SignatureVerificationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InvalidSigner_error_selector = 0x815e1d64; uint256 constant InvalidSigner_error_length = 0x04; /* * error InvalidSignature() * - Defined in SignatureVerificationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InvalidSignature_error_selector = 0x8baa579f; uint256 constant InvalidSignature_error_length = 0x04; /* * error BadContractSignature() * - Defined in SignatureVerificationErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant BadContractSignature_error_selector = 0x4f7fb80d; uint256 constant BadContractSignature_error_length = 0x04; /* * error InvalidERC721TransferAmount(uint256 amount) * - Defined in TokenTransferrerErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: amount * Revert buffer is memory[0x1c:0x40] */ uint256 constant InvalidERC721TransferAmount_error_selector = 0x69f95827; uint256 constant InvalidERC721TransferAmount_error_amount_ptr = 0x20; uint256 constant InvalidERC721TransferAmount_error_length = 0x24; /* * error MissingItemAmount() * - Defined in TokenTransferrerErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant MissingItemAmount_error_selector = 0x91b3e514; uint256 constant MissingItemAmount_error_length = 0x04; /* * error UnusedItemParameters() * - Defined in TokenTransferrerErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant UnusedItemParameters_error_selector = 0x6ab37ce7; uint256 constant UnusedItemParameters_error_length = 0x04; /* * error NoReentrantCalls() * - Defined in ReentrancyErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant NoReentrantCalls_error_selector = 0x7fa8a987; uint256 constant NoReentrantCalls_error_length = 0x04; /* * error OrderAlreadyFilled(bytes32 orderHash) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderHash * Revert buffer is memory[0x1c:0x40] */ uint256 constant OrderAlreadyFilled_error_selector = 0x10fda3e1; uint256 constant OrderAlreadyFilled_error_orderHash_ptr = 0x20; uint256 constant OrderAlreadyFilled_error_length = 0x24; /* * error InvalidTime(uint256 startTime, uint256 endTime) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: startTime * - 0x40: endTime * Revert buffer is memory[0x1c:0x60] */ uint256 constant InvalidTime_error_selector = 0x21ccfeb7; uint256 constant InvalidTime_error_startTime_ptr = 0x20; uint256 constant InvalidTime_error_endTime_ptr = 0x40; uint256 constant InvalidTime_error_length = 0x44; /* * error InvalidConduit(bytes32 conduitKey, address conduit) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: conduitKey * - 0x40: conduit * Revert buffer is memory[0x1c:0x60] */ uint256 constant InvalidConduit_error_selector = 0x1cf99b26; uint256 constant InvalidConduit_error_conduitKey_ptr = 0x20; uint256 constant InvalidConduit_error_conduit_ptr = 0x40; uint256 constant InvalidConduit_error_length = 0x44; /* * error MissingOriginalConsiderationItems() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant MissingOriginalConsiderationItems_error_selector = 0x466aa616; uint256 constant MissingOriginalConsiderationItems_error_length = 0x04; /* * error InvalidCallToConduit(address conduit) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: conduit * Revert buffer is memory[0x1c:0x40] */ uint256 constant InvalidCallToConduit_error_selector = 0xd13d53d4; uint256 constant InvalidCallToConduit_error_conduit_ptr = 0x20; uint256 constant InvalidCallToConduit_error_length = 0x24; /* * error ConsiderationNotMet( * uint256 orderIndex, * uint256 considerationIndex, * uint256 shortfallAmount * ) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderIndex * - 0x40: considerationIndex * - 0x60: shortfallAmount * Revert buffer is memory[0x1c:0x80] */ uint256 constant ConsiderationNotMet_error_selector = 0xa5f54208; uint256 constant ConsiderationNotMet_error_orderIndex_ptr = 0x20; uint256 constant ConsiderationNotMet_error_considerationIndex_ptr = 0x40; uint256 constant ConsiderationNotMet_error_shortfallAmount_ptr = 0x60; uint256 constant ConsiderationNotMet_error_length = 0x64; /* * error InsufficientNativeTokensSupplied() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InsufficientNativeTokensSupplied_error_selector = 0x8ffff980; uint256 constant InsufficientNativeTokensSupplied_error_length = 0x04; /* * error NativeTokenTransferGenericFailure(address account, uint256 amount) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: account * - 0x40: amount * Revert buffer is memory[0x1c:0x60] */ uint256 constant NativeTokenTransferGenericFailure_error_selector = 0xbc806b96; uint256 constant NativeTokenTransferGenericFailure_error_account_ptr = 0x20; uint256 constant NativeTokenTransferGenericFailure_error_amount_ptr = 0x40; uint256 constant NativeTokenTransferGenericFailure_error_length = 0x44; /* * error PartialFillsNotEnabledForOrder() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant PartialFillsNotEnabledForOrder_error_selector = 0xa11b63ff; uint256 constant PartialFillsNotEnabledForOrder_error_length = 0x04; /* * error OrderIsCancelled(bytes32 orderHash) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderHash * Revert buffer is memory[0x1c:0x40] */ uint256 constant OrderIsCancelled_error_selector = 0x1a515574; uint256 constant OrderIsCancelled_error_orderHash_ptr = 0x20; uint256 constant OrderIsCancelled_error_length = 0x24; /* * error OrderPartiallyFilled(bytes32 orderHash) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderHash * Revert buffer is memory[0x1c:0x40] */ uint256 constant OrderPartiallyFilled_error_selector = 0xee9e0e63; uint256 constant OrderPartiallyFilled_error_orderHash_ptr = 0x20; uint256 constant OrderPartiallyFilled_error_length = 0x24; /* * error CannotCancelOrder() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant CannotCancelOrder_error_selector = 0xfed398fc; uint256 constant CannotCancelOrder_error_length = 0x04; /* * error BadFraction() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant BadFraction_error_selector = 0x5a052b32; uint256 constant BadFraction_error_length = 0x04; /* * error InvalidMsgValue(uint256 value) * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: value * Revert buffer is memory[0x1c:0x40] */ uint256 constant InvalidMsgValue_error_selector = 0xa61be9f0; uint256 constant InvalidMsgValue_error_value_ptr = 0x20; uint256 constant InvalidMsgValue_error_length = 0x24; /* * error InvalidBasicOrderParameterEncoding() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InvalidBasicOrderParameterEncoding_error_selector = 0x39f3e3fd; uint256 constant InvalidBasicOrderParameterEncoding_error_length = 0x04; /* * error NoSpecifiedOrdersAvailable() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant NoSpecifiedOrdersAvailable_error_selector = 0xd5da9a1b; uint256 constant NoSpecifiedOrdersAvailable_error_length = 0x04; /* * error InvalidNativeOfferItem() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InvalidNativeOfferItem_error_selector = 0x12d3f5a3; uint256 constant InvalidNativeOfferItem_error_length = 0x04; /* * error ConsiderationLengthNotEqualToTotalOriginal() * - Defined in ConsiderationEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant ConsiderationLengthNotEqualToTotalOriginal_error_selector = ( 0x2165628a ); uint256 constant ConsiderationLengthNotEqualToTotalOriginal_error_length = 0x04; /* * error Panic(uint256 code) * - Built-in Solidity error * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: code * Revert buffer is memory[0x1c:0x40] */ uint256 constant Panic_error_selector = 0x4e487b71; uint256 constant Panic_error_code_ptr = 0x20; uint256 constant Panic_error_length = 0x24; uint256 constant Panic_arithmetic = 0x11; // uint256 constant Panic_resource = 0x41;
{ "remappings": [ "clones-with-immutable-args/=lib/clones-with-immutable-args/src/", "create2-clones-with-immutable-args/=lib/create2-clones-with-immutable-args/src/", "create2-helpers/=lib/create2-clones-with-immutable-args/lib/create2-helpers/src/", "forge-std/=lib/forge-std/src/", "eip4626/=lib/foundry_eip-4626/src/", "gpl/=lib/gpl/src/", "solmate/=lib/solmate/src/", "seaport/=lib/seaport/contracts/", "seaport-core/=lib/seaport-core/", "seaport-types/=lib/seaport-types/", "seaport-sol/=lib/seaport-sol/", "murky/=lib/murky/src/", "core/=src/", "@openzeppelin/=lib/seaport/lib/openzeppelin-contracts/", "@rari-capital/solmate/=lib/seaport/lib/solmate/", "auction/=lib/gpl/lib/auction-house/src/", "ds-test/=lib/ds-test/src/", "erc4626-tests/=lib/seaport/lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts/=lib/seaport/lib/openzeppelin-contracts/", "openzeppelin/=lib/gpl/lib/openzeppelin-contracts/contracts/", "solady/=lib/solady/", "solarray/=lib/seaport/lib/solarray/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"CreateFail","type":"error"},{"inputs":[],"name":"InvalidRedeemSize","type":"error"},{"inputs":[{"internalType":"enum IVaultImplementation.InvalidRequestReason","name":"reason","type":"uint8"}],"name":"InvalidRequest","type":"error"},{"inputs":[{"internalType":"enum IPublicVault.InvalidVaultStates","name":"","type":"uint8"}],"name":"InvalidVaultState","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"","type":"bool"}],"name":"AllowListEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"","type":"address"},{"indexed":false,"internalType":"bool","name":"","type":"bool"}],"name":"AllowListUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"","type":"address"}],"name":"DelegateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"IncrementNonce","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lienId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"LienOpen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"epoch","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"liensOpenForEpoch","type":"uint256"}],"name":"LiensOpenForEpochRemaining","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"NonceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"currentEpoch","type":"uint256"}],"name":"ProcessEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newSlope","type":"uint256"}],"name":"SlopeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeInShares","type":"uint256"}],"name":"StrategistFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[],"name":"VaultShutdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"address","name":"withdrawProxy","type":"address"}],"name":"WithdrawProxyDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawReserveTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newYintercept","type":"uint256"}],"name":"YInterceptChanged","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"COLLATERAL_TOKEN","outputs":[{"internalType":"contract ICollateralToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EPOCH_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"IMPL_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"ROUTER","outputs":[{"internalType":"contract IAstariaRouter","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"START","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"VAULT_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"accrue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"domainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"epochEndTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"}],"name":"getAllowList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEpoch","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"epoch","type":"uint64"}],"name":"getEpochData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"getEpochEnd","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"end","type":"uint64"}],"name":"getLienEpoch","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getLiquidationWithdrawRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPublicVaultState","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint40","name":"","type":"uint40"},{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getShutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSlope","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStrategistNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVirtualBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"epoch","type":"uint64"}],"name":"getWithdrawProxy","outputs":[{"internalType":"contract IWithdrawProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getYIntercept","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incrementNonce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"delegate","type":"address"},{"internalType":"bool","name":"allowListEnabled","type":"bool"},{"internalType":"address[]","name":"allowList","type":"address[]"},{"internalType":"uint256","name":"depositCap","type":"uint256"}],"internalType":"struct IVaultImplementation.InitParams","name":"params","type":"tuple"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"modifyAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newCap","type":"uint256"}],"name":"modifyDepositCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint64","name":"epoch","type":"uint64"}],"name":"redeemFutureEpoch","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegate_","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"skim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionWindow","type":"uint256"},{"internalType":"uint256","name":"lienSlope","type":"uint256"},{"internalType":"uint64","name":"lienEnd","type":"uint64"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"owed","type":"uint256"}],"name":"stopLien","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeToEpochEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"timeToEpochEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeToSecondEpochEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferWithdrawReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"decreaseInSlope","type":"uint256"},{"internalType":"uint256","name":"interestPaid","type":"uint256"},{"internalType":"uint256","name":"decreaseInYIntercept","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"lienEnd","type":"uint64"},{"internalType":"bool","name":"isRepayment","type":"bool"}],"internalType":"struct IPublicVault.UpdateVaultParams","name":"params","type":"tuple"}],"name":"updateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50614975806100206000396000f3fe6080604052600436106103f95760003560e01c8063834029ba11610211578063c63d75b611610122578063dc2fbaee116100b0578063ef8b30f711610077578063ef8b30f714610c28578063f5f1f1a714610c48578063f698da2514610c5d578063f8ba4cff14610c72578063fc0e74d114610c8757005b8063dc2fbaee14610b8c578063dd62ed3e14610ba1578063dfb2b64514610bc1578063ea114d1d14610bd6578063eceea7e714610beb57005b8063ce96cb77116100f4578063ce96cb7714610aec578063cebbdf2314610b0c578063d505accf14610b2c578063d5176d2314610b4c578063d905777e14610b6c57005b8063c63d75b614610727578063c6e6f59214610a97578063ca5eb5e114610ab7578063cb58189d14610ad757005b8063ac4746ab1161019f578063b97dd9e211610171578063b97dd9e214610a23578063ba08765214610a38578063ba9a061a14610a58578063c0e9b05314610a6d578063c237c70314610a8257005b8063ac4746ab146109b9578063b19c2c70146109ce578063b3d7f6b9146109e3578063b460af9414610a0357005b806395d89b41116101e357806395d89b411461092f5780639d8f8fcc14610944578063a18c380614610959578063a3a911ba14610979578063a9059cbb1461099957005b8063834029ba146108d05780638da5cb5b146108e557806390bec11d146108fa57806394bf804d1461090f57005b8063349f723d1161030b578063512974d61161029957806366d003ac1161026b57806366d003ac146108465780636e553f651461085b57806370a082311461087b57806379c84f9c1461089b5780637f65a114146108b057005b8063512974d6146107a9578063627cdcb914610807578063645006ca1461081c57806364e4cf3b1461083157005b80633c96ce12116102dd5780633c96ce1214610707578063402d267d14610727578063474a1e541461074957806347c78fef146107695780634cdad5061461078957005b8063349f723d146106855780633567fc47146106bd5780633644e515146106dd57806338d52e0f146106f257005b80631865c57d1161038857806323b872dd1161035a57806323b872dd146105e157806330040e7714610601578063313ce567146106165780633177e0fe1461063857806332fe7b261461065857005b80631865c57d1461054a5780631d5470e8146105a25780631dd19cb4146105b7578063200298bf146105cc57005b806307a2d13a116103cc57806307a2d13a1461049c578063095ea7b3146104bc5780630a28a477146104dc578063150b7a02146104fc57806318160ddd1461053557005b80624c970c1461040257806301e1d1141461042257806301ffc9a71461044a57806306fdde031461047a57005b3661040057005b005b34801561040e57600080fd5b5061040061041d366004614024565b610c9c565b34801561042e57600080fd5b50610437610e36565b6040519081526020015b60405180910390f35b34801561045657600080fd5b5061046a61046536600461406b565b610e52565b6040519015158152602001610441565b34801561048657600080fd5b5061048f610eda565b60405161044191906140e5565b3480156104a857600080fd5b506104376104b73660046140f8565b610f6d565b3480156104c857600080fd5b5061046a6104d7366004614129565b610fa1565b3480156104e857600080fd5b506104376104f73660046140f8565b611016565b34801561050857600080fd5b5061051c610517366004614155565b61104d565b6040516001600160e01b03199091168152602001610441565b34801561054157600080fd5b506104376111ce565b34801561055657600080fd5b5061055f6111de565b604080519788526001600160a01b039687166020890152949095169386019390935290151560608501521515608084015260a083015260c082015260e001610441565b3480156105ae57600080fd5b5061043761124c565b3480156105c357600080fd5b5061040061125f565b3480156105d857600080fd5b5061043761132b565b3480156105ed57600080fd5b5061046a6105fc3660046141f3565b611356565b34801561060d57600080fd5b5061043761144d565b34801561062257600080fd5b5060125b60405160ff9091168152602001610441565b34801561064457600080fd5b50610400610653366004614242565b611460565b34801561066457600080fd5b5061066d6114fd565b6040516001600160a01b039091168152602001610441565b34801561069157600080fd5b506106a56106a036600461427b565b611509565b6040516001600160401b039091168152602001610441565b3480156106c957600080fd5b506104006106d8366004614296565b61154a565b3480156106e957600080fd5b50610437611631565b3480156106fe57600080fd5b5061066d61163b565b34801561071357600080fd5b506104006107223660046140f8565b611645565b34801561073357600080fd5b506104376107423660046142ae565b5060001990565b34801561075557600080fd5b506104006107643660046142cb565b611677565b34801561077557600080fd5b5061046a6107843660046142ae565b6117ae565b34801561079557600080fd5b506104376107a43660046140f8565b6117fc565b3480156107b557600080fd5b506107be611807565b60408051978852602088019690965264ffffffffff909416948601949094526001600160401b039091166060850152608084015260a083019190915260c082015260e001610441565b34801561081357600080fd5b50610400611865565b34801561082857600080fd5b5061043761192e565b34801561083d57600080fd5b50610400611aac565b34801561085257600080fd5b5061066d611df9565b34801561086757600080fd5b50610437610876366004614305565b611e15565b34801561088757600080fd5b506104376108963660046142ae565b611f32565b3480156108a757600080fd5b50610437611f5e565b3480156108bc57600080fd5b506104376108cb3660046140f8565b611f71565b3480156108dc57600080fd5b50610400611f99565b3480156108f157600080fd5b5061066d61201c565b34801561090657600080fd5b50610437612028565b34801561091b57600080fd5b5061043761092a366004614305565b612032565b34801561093b57600080fd5b5061048f612147565b34801561095057600080fd5b506104376121c6565b34801561096557600080fd5b506104376109743660046140f8565b6121d0565b34801561098557600080fd5b5061043761099436600461432a565b612201565b3480156109a557600080fd5b5061046a6109b4366004614129565b612220565b3480156109c557600080fd5b50610437612298565b3480156109da57600080fd5b506104006122a4565b3480156109ef57600080fd5b506104376109fe3660046140f8565b612755565b348015610a0f57600080fd5b50610437610a1e36600461437b565b61277b565b348015610a2f57600080fd5b506106a56127c1565b348015610a4457600080fd5b50610437610a5336600461437b565b6127e4565b348015610a6457600080fd5b50610437612815565b348015610a7957600080fd5b5061046a612821565b348015610a8e57600080fd5b5061062661283e565b348015610aa357600080fd5b50610437610ab23660046140f8565b61284a565b348015610ac357600080fd5b50610400610ad23660046142ae565b612871565b348015610ae357600080fd5b506104376128f3565b348015610af857600080fd5b50610437610b073660046142ae565b6128ff565b348015610b1857600080fd5b5061066d610b2736600461427b565b612931565b348015610b3857600080fd5b50610400610b473660046143cc565b61296d565b348015610b5857600080fd5b506106a5610b673660046140f8565b612bcf565b348015610b7857600080fd5b50610437610b873660046142ae565b612c03565b348015610b9857600080fd5b50610400612c30565b348015610bad57600080fd5b50610437610bbc36600461443d565b612caf565b348015610bcd57600080fd5b50610437612ceb565b348015610be257600080fd5b50610437612cfe565b348015610bf757600080fd5b50610c0b610c0636600461427b565b612d13565b604080519283526001600160a01b03909116602083015201610441565b348015610c3457600080fd5b50610437610c433660046140f8565b612d5a565b348015610c5457600080fd5b5061066d612d65565b348015610c6957600080fd5b50610437612dd0565b348015610c7e57600080fd5b50610437612e4f565b348015610c9357600080fd5b50610400612e61565b610ca4612ed8565b6000610cae612f60565b9050610cb981612f8e565b50610cca8186836001015403612ffc565b6000610cd585611509565b9050610ce18282613033565b6000610cf5826001600160401b0316611f71565b905087811015610e2c57610d0983836130ce565b6001600160401b0382166000908152600684016020526040902054600160401b90046001600160a01b0316610d3c6114fd565b6001600160a01b03166341700b976040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9d919061446b565b6001600160a01b031663b88d4fde308389898e604051602001610dca929190918252602082015260400190565b6040516020818303038152906040526040518563ffffffff1660e01b8152600401610df89493929190614488565b600060405180830381600087803b158015610e1257600080fd5b505af1158015610e26573d6000803e3d6000fd5b50505050505b5050505050505050565b600080610e41612f60565b9050610e4c816132c7565b91505090565b60006001600160e01b031982166360e4143360e01b1480610e8357506001600160e01b031982166371c7f1b560e11b145b80610e9e57506001600160e01b0319821663043eff2d60e51b145b80610eb957506001600160e01b031982166301342f9f60e31b145b80610ed457506001600160e01b031982166301ffc9a760e01b145b92915050565b6060610ee461163b565b6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610f21573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f4991908101906144db565b604051602001610f599190614587565b604051602081830303815290604052905090565b600080610f786111ce565b90508015610f9857610f93610f8b610e36565b849083613304565b610f9a565b825b9392505050565b600080610fac613322565b33600081815260028301602090815260408083206001600160a01b038a16808552908352928190208890555187815293945090927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a35060019392505050565b6000806110216111ce565b9050801561103d57610f9381611035610e36565b859190613350565b678ac7230489e800009392505050565b60006110576114fd565b6001600160a01b0316866001600160a01b03161480156110f0575061107a6114fd565b6001600160a01b03166341700b976040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110db919061446b565b6001600160a01b0316336001600160a01b0316145b156111bc57600080808080611107878901896145b9565b94509450945094509450600061111b612f60565b9050806005015486111561114e57600960405163201f67df60e01b8152600401611145919061462b565b60405180910390fd5b8060030154868260050154611163919061465b565b101561118557600560405163201f67df60e01b8152600401611145919061462b565b85816005016000828254611199919061465b565b909155506111aa90508a8587613376565b6111b586848461343c565b5050505050505b50630a85bd0160e11b95945050505050565b60006111d8613322565b54919050565b6000806000806000806000806111f261346e565b80546001820154919250906001600160a01b031661120e61201c565b6001840154600285015460ff600160a01b8304811692600160a81b90041690611235612dd0565b959e949d50929b5090995097509550909350915050565b6000611256612f60565b60040154905090565b6000611269612f60565b90506000816005015461127a61163b565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e4919061466e565b6112ee919061465b565b90508015611327578082600501600082825461130a9190614687565b90915550508154611327908390611322908490614687565b61349c565b5050565b6000611351611338612f60565b60020154600160281b90046001600160401b0316611f71565b905090565b600080611361613322565b6001600160a01b0386166000908152600282016020908152604080832033845290915290205490915060001981146113c45761139d848261465b565b6001600160a01b038716600090815260028401602090815260408083203384529091529020555b6001600160a01b0386166000908152600183016020526040812080548692906113ee90849061465b565b90915550506001600160a01b03808616600081815260018501602052604090819020805488019055519091881690600080516020614920833981519152906114399088815260200190565b60405180910390a350600195945050505050565b600061145761346e565b60020154905090565b61146861201c565b6001600160a01b0316336001600160a01b03161461148557600080fd5b8061148e61346e565b6001600160a01b03841660008181526003929092016020908152604092839020805460ff1916941515949094179093558151908152831515928101929092527f73121574a4eadb4cfdeb2ba56a6a88067b03edd1f0a0dfcac0a5a95682a2436791015b60405180910390a15050565b600061135160006134cf565b6000610ed4600161153b61151b612815565b611525908661469a565b6001600160401b0316611536612298565b6134f4565b611545919061465b565b61350c565b611552613522565b600061155c612f60565b905061156781612f8e565b5081606001358160050160008282546115809190614687565b90915550611596905060c0830160a084016146c1565b156115e5578135156115c45760018101546000906115b69084359061465b565b90506115c28282612ffc565b505b6115e0816115db6106a060a086016080870161427b565b613033565b611623565b6115f560c0830160a084016146c1565b158015611606575060008260400135115b15611623576116238183604001358360000154611322919061465b565b611327818360200135613619565b6000611351613687565b6000611351613691565b61164d61201c565b6001600160a01b0316336001600160a01b03161461166a57600080fd5b8061167361346e565b5550565b61167f6114fd565b6001600160a01b0316336001600160a01b03161461169c57600080fd5b60006116a661346e565b905060006116b760208401846142ae565b6001600160a01b0316146116f5576116d260208301836142ae565b6001820180546001600160a01b0319166001600160a01b03929092169190911790555b6060820135815561170c60408301602084016146c1565b156113275760018101805460ff60a01b1916600160a01b17905560005b61173660408401846146de565b90508110156117a957600160038301600061175460408701876146de565b8581811061176457611764614727565b905060200201602081019061177991906142ae565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101611729565b505050565b6000806117b961346e565b6001810154909150600160a01b900460ff166117d85750600192915050565b6001600160a01b039092166000908152600390920160205250604090205460ff1690565b6000610ed482610f6d565b60008060008060008060008061181b612f60565b80546001820154600283015460038401546004850154600590950154939d929c5064ffffffffff82169b50600160281b9091046001600160401b0316995097509195509350915050565b600061186f61346e565b905061187961201c565b6001600160a01b0316336001600160a01b0316141580156118a7575060018101546001600160a01b03163314155b156118c857600060405163eac08f1960e01b8152600401611145919061473d565b60806118d560014361465b565b40901c60001c8160020160008282546118ee9190614687565b909155505060028101546040519081527fc6f316165836b9a9ca658ba2e3bbf32b3acff9aca1956fc77393fb506d26b0d69060200160405180910390a150565b6000600461193a61163b565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199b9190614751565b60ff161015611a245760016119ae61163b565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0f9190614751565b611a19919061476e565b61135190600a61486b565b6008611a2e61163b565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8f9190614751565b60ff161015611aa25760026119ae61163b565b60066119ae61163b565b6000611ab6612f60565b6002810154909150600160281b90046001600160401b0316611ad55750565b600081600601600060018460020160059054906101000a90046001600160401b0316611b01919061469a565b6001600160401b03168152602081019190915260400160002054600160401b90046001600160a01b031690508015611ca3576000611b3d61163b565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015611b83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba7919061466e565b905080836003015411611bc557506003820180546000909155611bd1565b60038301805482900390555b8015611ca157611bf48282611be461163b565b6001600160a01b0316919061369d565b80836005016000828254611c08919061465b565b9091555050604051630733d16f60e21b8152600481018290526001600160a01b03831690631ccf45bc90602401600060405180830381600087803b158015611c4f57600080fd5b505af1158015611c63573d6000803e3d6000fd5b505050507f4fe4d5aa830b30718c35f3d40b9af9a9b42bcba60975357a1b1b40fad5c4eee481604051611c9891815260200190565b60405180910390a15b505b6002820154600160281b90046001600160401b031660009081526006830160205260409020546003830154600160401b9091046001600160a01b03169015801590611cf35750611cf161132b565b155b8015611d0757506001600160a01b03811615155b156117a9576003830154604051630575d1a760e11b81526000916001600160a01b03841691630aeba34e91611d529187906004019182526001600160a01b0316602082015260400190565b6020604051808303816000875af1158015611d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d95919061466e565b6003850180548290039055604051630733d16f60e21b8152600481018290529091506001600160a01b03841690631ccf45bc90602401600060405180830381600087803b158015611de557600080fd5b505af1158015610e2c573d6000803e3d6000fd5b6000611e0361371e565b15611e0d57503090565b61135161201c565b6000611e1f6114fd565b6001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e80919061487a565b15611ea157600460405163eac08f1960e01b8152600401611145919061473d565b611ea961346e565b60010154600160a81b900460ff1615611ed857600360405163eac08f1960e01b8152600401611145919061473d565b6000611ee261346e565b6001810154909150600160a01b900460ff1615611f20576001600160a01b038316600090815260038201602052604090205460ff16611f2057600080fd5b611f2a8484613733565b949350505050565b6000611f3c613322565b6001600160a01b03909216600090815260019290920160205250604090205490565b6000611f68612f60565b60010154905090565b600080611f7d836121d0565b9050804210611f8f5750600092915050565b610f9a428261465b565b611fa161201c565b6001600160a01b0316336001600160a01b031614611fbe57600080fd5b6000611fc861346e565b6001018054911515600160a01b0260ff60a01b19909216919091179055604051600081527f0efe10ef116fae4939f66482c28a1b970a12ed19dc4ced68d2080c5558106f11906020015b60405180910390a1565b600061135160156134cf565b600061135161383f565b600061203c6114fd565b6001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612079573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209d919061487a565b156120be57600460405163eac08f1960e01b8152600401611145919061473d565b6120c661346e565b60010154600160a81b900460ff16156120f557600360405163eac08f1960e01b8152600401611145919061473d565b60006120ff61346e565b6001810154909150600160a01b900460ff161561213d576001600160a01b038316600090815260038201602052604090205460ff1661213d57600080fd5b611f2a848461387f565b606061215161163b565b6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561218e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526121b691908101906144db565b604051602001610f599190614897565b60006111d8612f60565b60006121da612298565b6121e5836001614687565b6121ef91906148c5565b6121f7612815565b610ed49190614687565b600061221761220e612f60565b8686868661393c565b95945050505050565b60008061222b613322565b33600090815260018201602052604081208054929350859290919061225190849061465b565b90915550506001600160a01b038416600081815260018301602052604090819020805486019055513390600080516020614920833981519152906110049087815260200190565b6000611351605d613bd9565b60006122ae61132b565b11156122d057600360405163201f67df60e01b8152600401611145919061462b565b60006122da612f60565b60038101549091501561230357600460405163201f67df60e01b8152600401611145919061462b565b6002810154600160281b90046001600160401b03166000818152600683016020526040902054600160401b90046001600160a01b0316901561246157600082600601600060018560020160059054906101000a90046001600160401b031661236b919061469a565b6001600160401b03168152602081019190915260400160002054600160401b90046001600160a01b0316905080158015906124065750806001600160a01b031663989673b16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612403919061466e565b15155b1561245f57806001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561244657600080fd5b505af115801561245a573d6000803e3d6000fd5b505050505b505b60028201546001600160401b03600160281b9091048116600090815260068401602052604090205416156124ab57600660405163201f67df60e01b8152600401611145919061462b565b600060048301556001600160a01b038116156126d1576000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612501573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612525919061466e565b905061252f6111ce565b1561255557612550670de0b6b3a76400006125486111ce565b839190613304565b612558565b60005b60048085018290556040516302177ab760e11b81526001600160a01b0385169263042ef56e9261258c920190815260200190565b600060405180830381600087803b1580156125a657600080fd5b505af11580156125ba573d6000803e3d6000fd5b505050506000826001600160a01b031663b701e7276040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612622919061466e565b90508061262d610e36565b111561265e57612654846004015482612644610e36565b61264e919061465b565b90613bfb565b6003850155612666565b600060038501555b61269d846113228660040154670de0b6b3a7640000612685919061465b565b670de0b6b3a7640000612696610e36565b9190613304565b6126a642613c10565b60028501805464ffffffffff191664ffffffffff929092169190911790556126ce3083613c22565b50505b600282015460408051338152600160281b9092046001600160401b031660208301527f8cd75078c8772639bb2343d3a00c7118a4f7a6e8804bfbc31cd360582d2d2f5b910160405180910390a150600201805460016001600160401b03600160281b80840482169290920116026cffffffffffffffff000000000019909116179055565b6000806127606111ce565b9050801561103d57610f93612773610e36565b849083613350565b600061278684611016565b90506000612792612f60565b90506127b8818386868560020160059054906101000a90046001600160401b031661393c565b50509392505050565b60006127cb612f60565b60020154600160281b90046001600160401b0316919050565b6000806127ef612f60565b9050612217818686868560020160059054906101000a90046001600160401b031661393c565b6000611351603d613bd9565b600061282b61346e565b60010154600160a81b900460ff16919050565b60006113516014613c9c565b6000806128556111ce565b90508015610f9857610f9381612869610e36565b859190613304565b61287961201c565b6001600160a01b0316336001600160a01b03161461289657600080fd5b60006128a061346e565b6001810180546001600160a01b0319166001600160a01b0385169081179091556040519081529091507fbf313af507f7586dc28510c0974f0196ee356634bf104cf3ab61a28a2616c154906020016114f1565b6000611351607d613bd9565b60008061290a613322565b6001600160a01b0384166000908152600182016020526040902054909150610f9a90610f6d565b600061293b612f60565b6001600160401b039290921660009081526006909201602052506040902054600160401b90046001600160a01b031690565b428410156129bd5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401611145565b600060016129c9611631565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a8a8a6129f5613322565b6001600160a01b038f8116600090815260039290920160209081526040928390208054600181019091558351808301989098529582168784015293166060860152608085019190915260a084019290925260c08084018b90528251808503909101815260e08401909252815191012061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015612ae4573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612b1a5750876001600160a01b0316816001600160a01b0316145b612b575760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401611145565b85612b60613322565b6001600160a01b039283166000908152600291909101602090815260408083208b86168085529083529281902093909355915188815290928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000610ed4612bdc612298565b612be7846001614687565b612bf191906148c5565b612bf9612815565b6115459190614687565b600080612c0e613322565b6001600160a01b03909316600090815260019093016020525050604090205490565b612c3861201c565b6001600160a01b0316336001600160a01b031614612c5557600080fd5b6001612c5f61346e565b60019081018054921515600160a01b0260ff60a01b19909316929092179091556040519081527f0efe10ef116fae4939f66482c28a1b970a12ed19dc4ced68d2080c5558106f1190602001612012565b600080612cba613322565b6001600160a01b03948516600090815260029190910160209081526040808320959096168252939093525050205490565b6000612cf5612f60565b60030154905090565b600080612d09612f60565b6005015492915050565b6000806000612d20612f60565b6001600160401b039485166000908152600691909101602052604090205493841694600160401b9094046001600160a01b03169392505050565b6000610ed48261284a565b6000612d6f6114fd565b6001600160a01b031663f5f1f1a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611351919061446b565b604080517f2aef22f9d7df5f9d21c56d14029233f3fdaa91917727e1eb68e504d27072d6cd60208201527f044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d9181019190915246606082015230608082015260009060a00160405160208183030381529060405280519060200120905090565b6000611351612e5c612f60565b612f8e565b612e6961201c565b6001600160a01b0316336001600160a01b031614612e8657600080fd5b6001612e9061346e565b6001018054911515600160a81b0260ff60a81b199092169190911790556040517f43849b84f1a1ce86ba1205cd8a5d4fa1563bca4b169db452674f94b4b6ddaa6990600090a1565b612ee06114fd565b6001600160a01b03166341700b976040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f41919061446b565b6001600160a01b0316336001600160a01b031614612f5e57600080fd5b565b600080610ed460017fc8b9e850684c861cb4124c86f9eebbd425d1f899eefe14aef183cd9cd8e16ef061465b565b6000612f99826132c7565b8255612fa442613c10565b60028301805464ffffffffff191664ffffffffff9290921691909117905581546040519081527f0d929f3d1cc26451e13ef120a91a57d7b74aabeb7d27aea8659f79232ded5bb79060200160405180910390a1505490565b600182018190556040518181527f8658d090f98257c3dddbd5519a24e83bee296705ab98a9d4e3c2a95ab6ac8311906020016114f1565b6001600160401b03808216600090815260068401602052604081208054909216919061305e836148dc565b82546101009290920a6001600160401b038181021990931691831602179091558281166000818152600686016020908152604091829020548251938452909316928201929092527fc78e24d95d2fbcef8eeb6cf95914c9a7cfd906a017910a054d2404baac8512319250016114f1565b6001600160401b0381166000908152600683016020526040902054600160401b90046001600160a01b0316611327576132426131086114fd565b6001600160a01b0316631ff0c9d66040518163ffffffff1660e01b8152600401602060405180830381865afa158015613145573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613169919061446b565b6131716114fd565b600261317b61163b565b306131878760016148ff565b604051606095861b6bffffffffffffffffffffffff19908116602083015260f89590951b6001600160f81b031916603482015292851b84166035840152931b909116604982015260c09190911b6001600160c01b031916605d82015260650160408051601f19818403018152908290526bffffffffffffffffffffffff193060601b1660208301526001600160c01b031960c086901b16603483015290603c0160405160208183030381529060405280519060200120613cc1565b6001600160401b0382166000818152600685016020908152604091829020805468010000000000000000600160e01b031916600160401b6001600160a01b039687168102919091179182905583519485529004909316928201929092527fdb5d7e672e3c658b30325f67d117f17a38d180001c2027cca5b2f9d4b03b0ff291016114f1565b600281015460009081906132e29064ffffffffff164261465b565b835460018086015492935090916132fa918490613304565b610f9a9190614687565b600082600019048411830215820261331b57600080fd5b5091020490565b600080610ed460017f6c9d8be213da072972500acecface6c6d1d5ffbaace52819bc3770310729359261465b565b600082600019048411830215820261336757600080fd5b50910281810615159190040190565b6000613380612f60565b905061338b81612f8e565b50600083826001015461339e9190614687565b90506133aa8282612ffc565b6133b261132b565b6000036133d557600060405163201f67df60e01b8152600401611145919061462b565b60006133e78464ffffffffff16611509565b90506133f38382613d03565b604080518781526001600160401b03831660208201527f62a344dd82c6dba4b37f8fd2af14110b8674bb9abdca665ff3b06692935bbee1910160405180910390a1505050505050565b6134468282613d71565b6000613452828561465b565b905061346861345f6114fd565b82611be461163b565b50505050565b600080610ed460017f8db05f23e24c991e45d8dd3599daf8e419ee5ab93565cf65b18905286a24ec1461465b565b8082556040518181527f0d929f3d1cc26451e13ef120a91a57d7b74aabeb7d27aea8659f79232ded5bb7906020016114f1565b6000806134e6600119368181013560f01c90030190565b929092013560601c92915050565b60008161350057600080fd5b50808204910615150190565b6000600160401b821061351e57600080fd5b5090565b600061352c612f60565b6002810154909150600160281b90046001600160401b0316801580159061358c575060068201600061355f60018461469a565b6001600160401b03168152602081019190915260400160002054600160401b90046001600160a01b031633145b80613610575061359a6114fd565b6001600160a01b03166341700b976040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135fb919061446b565b6001600160a01b0316336001600160a01b0316145b61132757600080fd5b60006136236128f3565b141580156136315750600081115b1561132757600061364a6136436128f3565b8390613bfb565b905060006136746136596111ce565b83613662610e36565b61366c919061465b565b849190613304565b905061346861368161201c565b82613d90565b6000611351612dd0565b600061135160296134cf565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806134685760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401611145565b6000600161372a61283e565b60ff1614905090565b600061373e83612d5a565b90508060000361377e5760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b6044820152606401611145565b61378661192e565b81116137c65760405162461bcd60e51b815260206004820152600f60248201526e159053155157d513d3d7d4d3505313608a1b6044820152606401611145565b6137e53330856137d461163b565b6001600160a01b0316929190613df2565b6137ef8282613d90565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610ed48382613e8e565b60008061384a612f60565b6002810154909150610e4c9061387190600160281b90046001600160401b031660016148ff565b6001600160401b0316611f71565b600061388a83612755565b905061389461192e565b81116138d45760405162461bcd60e51b815260206004820152600f60248201526e159053155157d513d3d7d4d3505313608a1b6044820152606401611145565b6138e23330836137d461163b565b6138ec8284613d90565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610ed48184613e8e565b600080613947613322565b9050336001600160a01b038516146139bb576001600160a01b0384166000908152600282016020908152604080832033845290915290205460001981146139b957613992878261465b565b6001600160a01b038616600090815260028401602090815260408083203384529091529020555b505b60028701546001600160401b03600160281b909104811690841610156139f757600160405163201f67df60e01b8152600401611145919061462b565b613a00866117fc565b915081600003613a405760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401611145565b613a4861192e565b821015613a685760405163edb7a7ff60e01b815260040160405180910390fd5b6001600160a01b038416600090815260018201602052604081208054889290613a9290849061465b565b909155505030600081815260018301602052604090819020805489019055516001600160a01b0386169060008051602061492083398151915290613ad9908a815260200190565b60405180910390a3613aeb87846130ce565b60408051838152602081018890526001600160a01b03808716929088169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a46001600160401b0383166000908152600688016020526040908190205490516394bf804d60e01b8152600481018890526001600160a01b038781166024830152600160401b909204909116906394bf804d906044016020604051808303816000875af1158015613baa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bce919061466e565b505095945050505050565b600080613bf0600119368181013560f01c90030190565b929092013592915050565b6000610f9a8383670de0b6b3a7640000613304565b6000600160281b821061351e57600080fd5b6000613c2c613322565b6001600160a01b0384166000908152600182016020526040812080549293508492909190613c5b90849061465b565b9091555050805482900381556040518281526000906001600160a01b03851690600080516020614920833981519152906020015b60405180910390a3505050565b600080613cb3600119368181013560f01c90030190565b929092013560f81c92915050565b6000806000613cd08686613f2b565b915091508381836000f592506001600160a01b0383166127b857604051631d7fde3160e31b815260040160405180910390fd5b6001600160401b038181166000818152600685016020908152604091829020805480861660010190951667ffffffffffffffff199095168517905581519283528201929092527fc78e24d95d2fbcef8eeb6cf95914c9a7cfd906a017910a054d2404baac85123191016114f1565b6001600160a01b038216158015906117a9576117a98383611be461163b565b6000613d9a613322565b905081816000016000828254613db09190614687565b90915550506001600160a01b03831660008181526001830160209081526040808320805487019055518581526000805160206149208339815191529101613c8f565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b03841660248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080613e875760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401611145565b5050505050565b6000613e98612f60565b8054840181556005810180548501905590506000613eb461346e565b805490915015801590613ecf57508054613ecc610e36565b10155b15613ef057600860405163201f67df60e01b8152600401611145919061462b565b81546040519081527f0d929f3d1cc26451e13ef120a91a57d7b74aabeb7d27aea8659f79232ded5bb79060200160405180910390a150505050565b8051604051606160f81b81526039820160f081811b60018401526f3d81600a3d39f33d3d3d3d363d3d376160801b600384015260028401901b601383018190526560373639366160d01b6015840152601b83015262013d7360e81b601d830152606085901b6020808401919091526c5af43d3d93803e603557fd5bf360981b603484015291926043810192909190850182604186015b60208210613fe05782518152602092830192601f199092019101613fc1565b915160001960208390036101000a011916825260f09390931b920191909152505b9250929050565b80356001600160401b038116811461401f57600080fd5b919050565b600080600080600060a0868803121561403c57600080fd5b853594506020860135935061405360408701614008565b94979396509394606081013594506080013592915050565b60006020828403121561407d57600080fd5b81356001600160e01b031981168114610f9a57600080fd5b60005b838110156140b0578181015183820152602001614098565b50506000910152565b600081518084526140d1816020860160208601614095565b601f01601f19169290920160200192915050565b602081526000610f9a60208301846140b9565b60006020828403121561410a57600080fd5b5035919050565b6001600160a01b038116811461412657600080fd5b50565b6000806040838503121561413c57600080fd5b823561414781614111565b946020939093013593505050565b60008060008060006080868803121561416d57600080fd5b853561417881614111565b9450602086013561418881614111565b93506040860135925060608601356001600160401b03808211156141ab57600080fd5b818801915088601f8301126141bf57600080fd5b8135818111156141ce57600080fd5b8960208285010111156141e057600080fd5b9699959850939650602001949392505050565b60008060006060848603121561420857600080fd5b833561421381614111565b9250602084013561422381614111565b929592945050506040919091013590565b801515811461412657600080fd5b6000806040838503121561425557600080fd5b823561426081614111565b9150602083013561427081614234565b809150509250929050565b60006020828403121561428d57600080fd5b610f9a82614008565b600060c082840312156142a857600080fd5b50919050565b6000602082840312156142c057600080fd5b8135610f9a81614111565b6000602082840312156142dd57600080fd5b81356001600160401b038111156142f357600080fd5b820160808185031215610f9a57600080fd5b6000806040838503121561431857600080fd5b82359150602083013561427081614111565b6000806000806080858703121561434057600080fd5b84359350602085013561435281614111565b9250604085013561436281614111565b915061437060608601614008565b905092959194509250565b60008060006060848603121561439057600080fd5b8335925060208401356143a281614111565b915060408401356143b281614111565b809150509250925092565b60ff8116811461412657600080fd5b600080600080600080600060e0888a0312156143e757600080fd5b87356143f281614111565b9650602088013561440281614111565b955060408801359450606088013593506080880135614420816143bd565b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561445057600080fd5b823561445b81614111565b9150602083013561427081614111565b60006020828403121561447d57600080fd5b8151610f9a81614111565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906144bb908301846140b9565b9695505050505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156144ed57600080fd5b81516001600160401b038082111561450457600080fd5b818401915084601f83011261451857600080fd5b81518181111561452a5761452a6144c5565b604051601f8201601f19908116603f01168101908382118183101715614552576145526144c5565b8160405282815287602084870101111561456b57600080fd5b61457c836020830160208801614095565b979650505050505050565b694153542d5661756c742d60b01b8152600082516145ac81600a850160208701614095565b91909101600a0192915050565b600080600080600060a086880312156145d157600080fd5b85359450602086013564ffffffffff811681146145ed57600080fd5b935060408601359250606086013561460481614111565b949793965091946080013592915050565b634e487b7160e01b600052602160045260246000fd5b60208101600a831061463f5761463f614615565b91905290565b634e487b7160e01b600052601160045260246000fd5b81810381811115610ed457610ed4614645565b60006020828403121561468057600080fd5b5051919050565b80820180821115610ed457610ed4614645565b6001600160401b038281168282160390808211156146ba576146ba614645565b5092915050565b6000602082840312156146d357600080fd5b8135610f9a81614234565b6000808335601e198436030181126146f557600080fd5b8301803591506001600160401b0382111561470f57600080fd5b6020019150600581901b360382131561400157600080fd5b634e487b7160e01b600052603260045260246000fd5b602081016005831061463f5761463f614615565b60006020828403121561476357600080fd5b8151610f9a816143bd565b60ff8281168282160390811115610ed457610ed4614645565b600181815b808511156147c25781600019048211156147a8576147a8614645565b808516156147b557918102915b93841c939080029061478c565b509250929050565b6000826147d957506001610ed4565b816147e657506000610ed4565b81600181146147fc576002811461480657614822565b6001915050610ed4565b60ff84111561481757614817614645565b50506001821b610ed4565b5060208310610133831016604e8410600b8410161715614845575081810a610ed4565b61484f8383614787565b806000190482111561486357614863614645565b029392505050565b6000610f9a60ff8416836147ca565b60006020828403121561488c57600080fd5b8151610f9a81614234565b654153542d562d60d01b8152600082516148b8816006850160208701614095565b9190910160060192915050565b8082028115828204841417610ed457610ed4614645565b60006001600160401b038216806148f5576148f5614645565b6000190192915050565b6001600160401b038181168382160190808211156146ba576146ba61464556feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212206372e7e3c4d6cc90230cd62e366a1a1c6cd2b6d95796d557e17447032d3d3e6364736f6c63430008110033
Deployed Bytecode
0x6080604052600436106103f95760003560e01c8063834029ba11610211578063c63d75b611610122578063dc2fbaee116100b0578063ef8b30f711610077578063ef8b30f714610c28578063f5f1f1a714610c48578063f698da2514610c5d578063f8ba4cff14610c72578063fc0e74d114610c8757005b8063dc2fbaee14610b8c578063dd62ed3e14610ba1578063dfb2b64514610bc1578063ea114d1d14610bd6578063eceea7e714610beb57005b8063ce96cb77116100f4578063ce96cb7714610aec578063cebbdf2314610b0c578063d505accf14610b2c578063d5176d2314610b4c578063d905777e14610b6c57005b8063c63d75b614610727578063c6e6f59214610a97578063ca5eb5e114610ab7578063cb58189d14610ad757005b8063ac4746ab1161019f578063b97dd9e211610171578063b97dd9e214610a23578063ba08765214610a38578063ba9a061a14610a58578063c0e9b05314610a6d578063c237c70314610a8257005b8063ac4746ab146109b9578063b19c2c70146109ce578063b3d7f6b9146109e3578063b460af9414610a0357005b806395d89b41116101e357806395d89b411461092f5780639d8f8fcc14610944578063a18c380614610959578063a3a911ba14610979578063a9059cbb1461099957005b8063834029ba146108d05780638da5cb5b146108e557806390bec11d146108fa57806394bf804d1461090f57005b8063349f723d1161030b578063512974d61161029957806366d003ac1161026b57806366d003ac146108465780636e553f651461085b57806370a082311461087b57806379c84f9c1461089b5780637f65a114146108b057005b8063512974d6146107a9578063627cdcb914610807578063645006ca1461081c57806364e4cf3b1461083157005b80633c96ce12116102dd5780633c96ce1214610707578063402d267d14610727578063474a1e541461074957806347c78fef146107695780634cdad5061461078957005b8063349f723d146106855780633567fc47146106bd5780633644e515146106dd57806338d52e0f146106f257005b80631865c57d1161038857806323b872dd1161035a57806323b872dd146105e157806330040e7714610601578063313ce567146106165780633177e0fe1461063857806332fe7b261461065857005b80631865c57d1461054a5780631d5470e8146105a25780631dd19cb4146105b7578063200298bf146105cc57005b806307a2d13a116103cc57806307a2d13a1461049c578063095ea7b3146104bc5780630a28a477146104dc578063150b7a02146104fc57806318160ddd1461053557005b80624c970c1461040257806301e1d1141461042257806301ffc9a71461044a57806306fdde031461047a57005b3661040057005b005b34801561040e57600080fd5b5061040061041d366004614024565b610c9c565b34801561042e57600080fd5b50610437610e36565b6040519081526020015b60405180910390f35b34801561045657600080fd5b5061046a61046536600461406b565b610e52565b6040519015158152602001610441565b34801561048657600080fd5b5061048f610eda565b60405161044191906140e5565b3480156104a857600080fd5b506104376104b73660046140f8565b610f6d565b3480156104c857600080fd5b5061046a6104d7366004614129565b610fa1565b3480156104e857600080fd5b506104376104f73660046140f8565b611016565b34801561050857600080fd5b5061051c610517366004614155565b61104d565b6040516001600160e01b03199091168152602001610441565b34801561054157600080fd5b506104376111ce565b34801561055657600080fd5b5061055f6111de565b604080519788526001600160a01b039687166020890152949095169386019390935290151560608501521515608084015260a083015260c082015260e001610441565b3480156105ae57600080fd5b5061043761124c565b3480156105c357600080fd5b5061040061125f565b3480156105d857600080fd5b5061043761132b565b3480156105ed57600080fd5b5061046a6105fc3660046141f3565b611356565b34801561060d57600080fd5b5061043761144d565b34801561062257600080fd5b5060125b60405160ff9091168152602001610441565b34801561064457600080fd5b50610400610653366004614242565b611460565b34801561066457600080fd5b5061066d6114fd565b6040516001600160a01b039091168152602001610441565b34801561069157600080fd5b506106a56106a036600461427b565b611509565b6040516001600160401b039091168152602001610441565b3480156106c957600080fd5b506104006106d8366004614296565b61154a565b3480156106e957600080fd5b50610437611631565b3480156106fe57600080fd5b5061066d61163b565b34801561071357600080fd5b506104006107223660046140f8565b611645565b34801561073357600080fd5b506104376107423660046142ae565b5060001990565b34801561075557600080fd5b506104006107643660046142cb565b611677565b34801561077557600080fd5b5061046a6107843660046142ae565b6117ae565b34801561079557600080fd5b506104376107a43660046140f8565b6117fc565b3480156107b557600080fd5b506107be611807565b60408051978852602088019690965264ffffffffff909416948601949094526001600160401b039091166060850152608084015260a083019190915260c082015260e001610441565b34801561081357600080fd5b50610400611865565b34801561082857600080fd5b5061043761192e565b34801561083d57600080fd5b50610400611aac565b34801561085257600080fd5b5061066d611df9565b34801561086757600080fd5b50610437610876366004614305565b611e15565b34801561088757600080fd5b506104376108963660046142ae565b611f32565b3480156108a757600080fd5b50610437611f5e565b3480156108bc57600080fd5b506104376108cb3660046140f8565b611f71565b3480156108dc57600080fd5b50610400611f99565b3480156108f157600080fd5b5061066d61201c565b34801561090657600080fd5b50610437612028565b34801561091b57600080fd5b5061043761092a366004614305565b612032565b34801561093b57600080fd5b5061048f612147565b34801561095057600080fd5b506104376121c6565b34801561096557600080fd5b506104376109743660046140f8565b6121d0565b34801561098557600080fd5b5061043761099436600461432a565b612201565b3480156109a557600080fd5b5061046a6109b4366004614129565b612220565b3480156109c557600080fd5b50610437612298565b3480156109da57600080fd5b506104006122a4565b3480156109ef57600080fd5b506104376109fe3660046140f8565b612755565b348015610a0f57600080fd5b50610437610a1e36600461437b565b61277b565b348015610a2f57600080fd5b506106a56127c1565b348015610a4457600080fd5b50610437610a5336600461437b565b6127e4565b348015610a6457600080fd5b50610437612815565b348015610a7957600080fd5b5061046a612821565b348015610a8e57600080fd5b5061062661283e565b348015610aa357600080fd5b50610437610ab23660046140f8565b61284a565b348015610ac357600080fd5b50610400610ad23660046142ae565b612871565b348015610ae357600080fd5b506104376128f3565b348015610af857600080fd5b50610437610b073660046142ae565b6128ff565b348015610b1857600080fd5b5061066d610b2736600461427b565b612931565b348015610b3857600080fd5b50610400610b473660046143cc565b61296d565b348015610b5857600080fd5b506106a5610b673660046140f8565b612bcf565b348015610b7857600080fd5b50610437610b873660046142ae565b612c03565b348015610b9857600080fd5b50610400612c30565b348015610bad57600080fd5b50610437610bbc36600461443d565b612caf565b348015610bcd57600080fd5b50610437612ceb565b348015610be257600080fd5b50610437612cfe565b348015610bf757600080fd5b50610c0b610c0636600461427b565b612d13565b604080519283526001600160a01b03909116602083015201610441565b348015610c3457600080fd5b50610437610c433660046140f8565b612d5a565b348015610c5457600080fd5b5061066d612d65565b348015610c6957600080fd5b50610437612dd0565b348015610c7e57600080fd5b50610437612e4f565b348015610c9357600080fd5b50610400612e61565b610ca4612ed8565b6000610cae612f60565b9050610cb981612f8e565b50610cca8186836001015403612ffc565b6000610cd585611509565b9050610ce18282613033565b6000610cf5826001600160401b0316611f71565b905087811015610e2c57610d0983836130ce565b6001600160401b0382166000908152600684016020526040902054600160401b90046001600160a01b0316610d3c6114fd565b6001600160a01b03166341700b976040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9d919061446b565b6001600160a01b031663b88d4fde308389898e604051602001610dca929190918252602082015260400190565b6040516020818303038152906040526040518563ffffffff1660e01b8152600401610df89493929190614488565b600060405180830381600087803b158015610e1257600080fd5b505af1158015610e26573d6000803e3d6000fd5b50505050505b5050505050505050565b600080610e41612f60565b9050610e4c816132c7565b91505090565b60006001600160e01b031982166360e4143360e01b1480610e8357506001600160e01b031982166371c7f1b560e11b145b80610e9e57506001600160e01b0319821663043eff2d60e51b145b80610eb957506001600160e01b031982166301342f9f60e31b145b80610ed457506001600160e01b031982166301ffc9a760e01b145b92915050565b6060610ee461163b565b6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610f21573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f4991908101906144db565b604051602001610f599190614587565b604051602081830303815290604052905090565b600080610f786111ce565b90508015610f9857610f93610f8b610e36565b849083613304565b610f9a565b825b9392505050565b600080610fac613322565b33600081815260028301602090815260408083206001600160a01b038a16808552908352928190208890555187815293945090927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a35060019392505050565b6000806110216111ce565b9050801561103d57610f9381611035610e36565b859190613350565b678ac7230489e800009392505050565b60006110576114fd565b6001600160a01b0316866001600160a01b03161480156110f0575061107a6114fd565b6001600160a01b03166341700b976040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110db919061446b565b6001600160a01b0316336001600160a01b0316145b156111bc57600080808080611107878901896145b9565b94509450945094509450600061111b612f60565b9050806005015486111561114e57600960405163201f67df60e01b8152600401611145919061462b565b60405180910390fd5b8060030154868260050154611163919061465b565b101561118557600560405163201f67df60e01b8152600401611145919061462b565b85816005016000828254611199919061465b565b909155506111aa90508a8587613376565b6111b586848461343c565b5050505050505b50630a85bd0160e11b95945050505050565b60006111d8613322565b54919050565b6000806000806000806000806111f261346e565b80546001820154919250906001600160a01b031661120e61201c565b6001840154600285015460ff600160a01b8304811692600160a81b90041690611235612dd0565b959e949d50929b5090995097509550909350915050565b6000611256612f60565b60040154905090565b6000611269612f60565b90506000816005015461127a61163b565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e4919061466e565b6112ee919061465b565b90508015611327578082600501600082825461130a9190614687565b90915550508154611327908390611322908490614687565b61349c565b5050565b6000611351611338612f60565b60020154600160281b90046001600160401b0316611f71565b905090565b600080611361613322565b6001600160a01b0386166000908152600282016020908152604080832033845290915290205490915060001981146113c45761139d848261465b565b6001600160a01b038716600090815260028401602090815260408083203384529091529020555b6001600160a01b0386166000908152600183016020526040812080548692906113ee90849061465b565b90915550506001600160a01b03808616600081815260018501602052604090819020805488019055519091881690600080516020614920833981519152906114399088815260200190565b60405180910390a350600195945050505050565b600061145761346e565b60020154905090565b61146861201c565b6001600160a01b0316336001600160a01b03161461148557600080fd5b8061148e61346e565b6001600160a01b03841660008181526003929092016020908152604092839020805460ff1916941515949094179093558151908152831515928101929092527f73121574a4eadb4cfdeb2ba56a6a88067b03edd1f0a0dfcac0a5a95682a2436791015b60405180910390a15050565b600061135160006134cf565b6000610ed4600161153b61151b612815565b611525908661469a565b6001600160401b0316611536612298565b6134f4565b611545919061465b565b61350c565b611552613522565b600061155c612f60565b905061156781612f8e565b5081606001358160050160008282546115809190614687565b90915550611596905060c0830160a084016146c1565b156115e5578135156115c45760018101546000906115b69084359061465b565b90506115c28282612ffc565b505b6115e0816115db6106a060a086016080870161427b565b613033565b611623565b6115f560c0830160a084016146c1565b158015611606575060008260400135115b15611623576116238183604001358360000154611322919061465b565b611327818360200135613619565b6000611351613687565b6000611351613691565b61164d61201c565b6001600160a01b0316336001600160a01b03161461166a57600080fd5b8061167361346e565b5550565b61167f6114fd565b6001600160a01b0316336001600160a01b03161461169c57600080fd5b60006116a661346e565b905060006116b760208401846142ae565b6001600160a01b0316146116f5576116d260208301836142ae565b6001820180546001600160a01b0319166001600160a01b03929092169190911790555b6060820135815561170c60408301602084016146c1565b156113275760018101805460ff60a01b1916600160a01b17905560005b61173660408401846146de565b90508110156117a957600160038301600061175460408701876146de565b8581811061176457611764614727565b905060200201602081019061177991906142ae565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101611729565b505050565b6000806117b961346e565b6001810154909150600160a01b900460ff166117d85750600192915050565b6001600160a01b039092166000908152600390920160205250604090205460ff1690565b6000610ed482610f6d565b60008060008060008060008061181b612f60565b80546001820154600283015460038401546004850154600590950154939d929c5064ffffffffff82169b50600160281b9091046001600160401b0316995097509195509350915050565b600061186f61346e565b905061187961201c565b6001600160a01b0316336001600160a01b0316141580156118a7575060018101546001600160a01b03163314155b156118c857600060405163eac08f1960e01b8152600401611145919061473d565b60806118d560014361465b565b40901c60001c8160020160008282546118ee9190614687565b909155505060028101546040519081527fc6f316165836b9a9ca658ba2e3bbf32b3acff9aca1956fc77393fb506d26b0d69060200160405180910390a150565b6000600461193a61163b565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199b9190614751565b60ff161015611a245760016119ae61163b565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0f9190614751565b611a19919061476e565b61135190600a61486b565b6008611a2e61163b565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8f9190614751565b60ff161015611aa25760026119ae61163b565b60066119ae61163b565b6000611ab6612f60565b6002810154909150600160281b90046001600160401b0316611ad55750565b600081600601600060018460020160059054906101000a90046001600160401b0316611b01919061469a565b6001600160401b03168152602081019190915260400160002054600160401b90046001600160a01b031690508015611ca3576000611b3d61163b565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015611b83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba7919061466e565b905080836003015411611bc557506003820180546000909155611bd1565b60038301805482900390555b8015611ca157611bf48282611be461163b565b6001600160a01b0316919061369d565b80836005016000828254611c08919061465b565b9091555050604051630733d16f60e21b8152600481018290526001600160a01b03831690631ccf45bc90602401600060405180830381600087803b158015611c4f57600080fd5b505af1158015611c63573d6000803e3d6000fd5b505050507f4fe4d5aa830b30718c35f3d40b9af9a9b42bcba60975357a1b1b40fad5c4eee481604051611c9891815260200190565b60405180910390a15b505b6002820154600160281b90046001600160401b031660009081526006830160205260409020546003830154600160401b9091046001600160a01b03169015801590611cf35750611cf161132b565b155b8015611d0757506001600160a01b03811615155b156117a9576003830154604051630575d1a760e11b81526000916001600160a01b03841691630aeba34e91611d529187906004019182526001600160a01b0316602082015260400190565b6020604051808303816000875af1158015611d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d95919061466e565b6003850180548290039055604051630733d16f60e21b8152600481018290529091506001600160a01b03841690631ccf45bc90602401600060405180830381600087803b158015611de557600080fd5b505af1158015610e2c573d6000803e3d6000fd5b6000611e0361371e565b15611e0d57503090565b61135161201c565b6000611e1f6114fd565b6001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e80919061487a565b15611ea157600460405163eac08f1960e01b8152600401611145919061473d565b611ea961346e565b60010154600160a81b900460ff1615611ed857600360405163eac08f1960e01b8152600401611145919061473d565b6000611ee261346e565b6001810154909150600160a01b900460ff1615611f20576001600160a01b038316600090815260038201602052604090205460ff16611f2057600080fd5b611f2a8484613733565b949350505050565b6000611f3c613322565b6001600160a01b03909216600090815260019290920160205250604090205490565b6000611f68612f60565b60010154905090565b600080611f7d836121d0565b9050804210611f8f5750600092915050565b610f9a428261465b565b611fa161201c565b6001600160a01b0316336001600160a01b031614611fbe57600080fd5b6000611fc861346e565b6001018054911515600160a01b0260ff60a01b19909216919091179055604051600081527f0efe10ef116fae4939f66482c28a1b970a12ed19dc4ced68d2080c5558106f11906020015b60405180910390a1565b600061135160156134cf565b600061135161383f565b600061203c6114fd565b6001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612079573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209d919061487a565b156120be57600460405163eac08f1960e01b8152600401611145919061473d565b6120c661346e565b60010154600160a81b900460ff16156120f557600360405163eac08f1960e01b8152600401611145919061473d565b60006120ff61346e565b6001810154909150600160a01b900460ff161561213d576001600160a01b038316600090815260038201602052604090205460ff1661213d57600080fd5b611f2a848461387f565b606061215161163b565b6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561218e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526121b691908101906144db565b604051602001610f599190614897565b60006111d8612f60565b60006121da612298565b6121e5836001614687565b6121ef91906148c5565b6121f7612815565b610ed49190614687565b600061221761220e612f60565b8686868661393c565b95945050505050565b60008061222b613322565b33600090815260018201602052604081208054929350859290919061225190849061465b565b90915550506001600160a01b038416600081815260018301602052604090819020805486019055513390600080516020614920833981519152906110049087815260200190565b6000611351605d613bd9565b60006122ae61132b565b11156122d057600360405163201f67df60e01b8152600401611145919061462b565b60006122da612f60565b60038101549091501561230357600460405163201f67df60e01b8152600401611145919061462b565b6002810154600160281b90046001600160401b03166000818152600683016020526040902054600160401b90046001600160a01b0316901561246157600082600601600060018560020160059054906101000a90046001600160401b031661236b919061469a565b6001600160401b03168152602081019190915260400160002054600160401b90046001600160a01b0316905080158015906124065750806001600160a01b031663989673b16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612403919061466e565b15155b1561245f57806001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561244657600080fd5b505af115801561245a573d6000803e3d6000fd5b505050505b505b60028201546001600160401b03600160281b9091048116600090815260068401602052604090205416156124ab57600660405163201f67df60e01b8152600401611145919061462b565b600060048301556001600160a01b038116156126d1576000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612501573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612525919061466e565b905061252f6111ce565b1561255557612550670de0b6b3a76400006125486111ce565b839190613304565b612558565b60005b60048085018290556040516302177ab760e11b81526001600160a01b0385169263042ef56e9261258c920190815260200190565b600060405180830381600087803b1580156125a657600080fd5b505af11580156125ba573d6000803e3d6000fd5b505050506000826001600160a01b031663b701e7276040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612622919061466e565b90508061262d610e36565b111561265e57612654846004015482612644610e36565b61264e919061465b565b90613bfb565b6003850155612666565b600060038501555b61269d846113228660040154670de0b6b3a7640000612685919061465b565b670de0b6b3a7640000612696610e36565b9190613304565b6126a642613c10565b60028501805464ffffffffff191664ffffffffff929092169190911790556126ce3083613c22565b50505b600282015460408051338152600160281b9092046001600160401b031660208301527f8cd75078c8772639bb2343d3a00c7118a4f7a6e8804bfbc31cd360582d2d2f5b910160405180910390a150600201805460016001600160401b03600160281b80840482169290920116026cffffffffffffffff000000000019909116179055565b6000806127606111ce565b9050801561103d57610f93612773610e36565b849083613350565b600061278684611016565b90506000612792612f60565b90506127b8818386868560020160059054906101000a90046001600160401b031661393c565b50509392505050565b60006127cb612f60565b60020154600160281b90046001600160401b0316919050565b6000806127ef612f60565b9050612217818686868560020160059054906101000a90046001600160401b031661393c565b6000611351603d613bd9565b600061282b61346e565b60010154600160a81b900460ff16919050565b60006113516014613c9c565b6000806128556111ce565b90508015610f9857610f9381612869610e36565b859190613304565b61287961201c565b6001600160a01b0316336001600160a01b03161461289657600080fd5b60006128a061346e565b6001810180546001600160a01b0319166001600160a01b0385169081179091556040519081529091507fbf313af507f7586dc28510c0974f0196ee356634bf104cf3ab61a28a2616c154906020016114f1565b6000611351607d613bd9565b60008061290a613322565b6001600160a01b0384166000908152600182016020526040902054909150610f9a90610f6d565b600061293b612f60565b6001600160401b039290921660009081526006909201602052506040902054600160401b90046001600160a01b031690565b428410156129bd5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401611145565b600060016129c9611631565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a8a8a6129f5613322565b6001600160a01b038f8116600090815260039290920160209081526040928390208054600181019091558351808301989098529582168784015293166060860152608085019190915260a084019290925260c08084018b90528251808503909101815260e08401909252815191012061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015612ae4573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612b1a5750876001600160a01b0316816001600160a01b0316145b612b575760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401611145565b85612b60613322565b6001600160a01b039283166000908152600291909101602090815260408083208b86168085529083529281902093909355915188815290928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000610ed4612bdc612298565b612be7846001614687565b612bf191906148c5565b612bf9612815565b6115459190614687565b600080612c0e613322565b6001600160a01b03909316600090815260019093016020525050604090205490565b612c3861201c565b6001600160a01b0316336001600160a01b031614612c5557600080fd5b6001612c5f61346e565b60019081018054921515600160a01b0260ff60a01b19909316929092179091556040519081527f0efe10ef116fae4939f66482c28a1b970a12ed19dc4ced68d2080c5558106f1190602001612012565b600080612cba613322565b6001600160a01b03948516600090815260029190910160209081526040808320959096168252939093525050205490565b6000612cf5612f60565b60030154905090565b600080612d09612f60565b6005015492915050565b6000806000612d20612f60565b6001600160401b039485166000908152600691909101602052604090205493841694600160401b9094046001600160a01b03169392505050565b6000610ed48261284a565b6000612d6f6114fd565b6001600160a01b031663f5f1f1a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611351919061446b565b604080517f2aef22f9d7df5f9d21c56d14029233f3fdaa91917727e1eb68e504d27072d6cd60208201527f044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d9181019190915246606082015230608082015260009060a00160405160208183030381529060405280519060200120905090565b6000611351612e5c612f60565b612f8e565b612e6961201c565b6001600160a01b0316336001600160a01b031614612e8657600080fd5b6001612e9061346e565b6001018054911515600160a81b0260ff60a81b199092169190911790556040517f43849b84f1a1ce86ba1205cd8a5d4fa1563bca4b169db452674f94b4b6ddaa6990600090a1565b612ee06114fd565b6001600160a01b03166341700b976040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f41919061446b565b6001600160a01b0316336001600160a01b031614612f5e57600080fd5b565b600080610ed460017fc8b9e850684c861cb4124c86f9eebbd425d1f899eefe14aef183cd9cd8e16ef061465b565b6000612f99826132c7565b8255612fa442613c10565b60028301805464ffffffffff191664ffffffffff9290921691909117905581546040519081527f0d929f3d1cc26451e13ef120a91a57d7b74aabeb7d27aea8659f79232ded5bb79060200160405180910390a1505490565b600182018190556040518181527f8658d090f98257c3dddbd5519a24e83bee296705ab98a9d4e3c2a95ab6ac8311906020016114f1565b6001600160401b03808216600090815260068401602052604081208054909216919061305e836148dc565b82546101009290920a6001600160401b038181021990931691831602179091558281166000818152600686016020908152604091829020548251938452909316928201929092527fc78e24d95d2fbcef8eeb6cf95914c9a7cfd906a017910a054d2404baac8512319250016114f1565b6001600160401b0381166000908152600683016020526040902054600160401b90046001600160a01b0316611327576132426131086114fd565b6001600160a01b0316631ff0c9d66040518163ffffffff1660e01b8152600401602060405180830381865afa158015613145573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613169919061446b565b6131716114fd565b600261317b61163b565b306131878760016148ff565b604051606095861b6bffffffffffffffffffffffff19908116602083015260f89590951b6001600160f81b031916603482015292851b84166035840152931b909116604982015260c09190911b6001600160c01b031916605d82015260650160408051601f19818403018152908290526bffffffffffffffffffffffff193060601b1660208301526001600160c01b031960c086901b16603483015290603c0160405160208183030381529060405280519060200120613cc1565b6001600160401b0382166000818152600685016020908152604091829020805468010000000000000000600160e01b031916600160401b6001600160a01b039687168102919091179182905583519485529004909316928201929092527fdb5d7e672e3c658b30325f67d117f17a38d180001c2027cca5b2f9d4b03b0ff291016114f1565b600281015460009081906132e29064ffffffffff164261465b565b835460018086015492935090916132fa918490613304565b610f9a9190614687565b600082600019048411830215820261331b57600080fd5b5091020490565b600080610ed460017f6c9d8be213da072972500acecface6c6d1d5ffbaace52819bc3770310729359261465b565b600082600019048411830215820261336757600080fd5b50910281810615159190040190565b6000613380612f60565b905061338b81612f8e565b50600083826001015461339e9190614687565b90506133aa8282612ffc565b6133b261132b565b6000036133d557600060405163201f67df60e01b8152600401611145919061462b565b60006133e78464ffffffffff16611509565b90506133f38382613d03565b604080518781526001600160401b03831660208201527f62a344dd82c6dba4b37f8fd2af14110b8674bb9abdca665ff3b06692935bbee1910160405180910390a1505050505050565b6134468282613d71565b6000613452828561465b565b905061346861345f6114fd565b82611be461163b565b50505050565b600080610ed460017f8db05f23e24c991e45d8dd3599daf8e419ee5ab93565cf65b18905286a24ec1461465b565b8082556040518181527f0d929f3d1cc26451e13ef120a91a57d7b74aabeb7d27aea8659f79232ded5bb7906020016114f1565b6000806134e6600119368181013560f01c90030190565b929092013560601c92915050565b60008161350057600080fd5b50808204910615150190565b6000600160401b821061351e57600080fd5b5090565b600061352c612f60565b6002810154909150600160281b90046001600160401b0316801580159061358c575060068201600061355f60018461469a565b6001600160401b03168152602081019190915260400160002054600160401b90046001600160a01b031633145b80613610575061359a6114fd565b6001600160a01b03166341700b976040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135fb919061446b565b6001600160a01b0316336001600160a01b0316145b61132757600080fd5b60006136236128f3565b141580156136315750600081115b1561132757600061364a6136436128f3565b8390613bfb565b905060006136746136596111ce565b83613662610e36565b61366c919061465b565b849190613304565b905061346861368161201c565b82613d90565b6000611351612dd0565b600061135160296134cf565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806134685760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401611145565b6000600161372a61283e565b60ff1614905090565b600061373e83612d5a565b90508060000361377e5760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b6044820152606401611145565b61378661192e565b81116137c65760405162461bcd60e51b815260206004820152600f60248201526e159053155157d513d3d7d4d3505313608a1b6044820152606401611145565b6137e53330856137d461163b565b6001600160a01b0316929190613df2565b6137ef8282613d90565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610ed48382613e8e565b60008061384a612f60565b6002810154909150610e4c9061387190600160281b90046001600160401b031660016148ff565b6001600160401b0316611f71565b600061388a83612755565b905061389461192e565b81116138d45760405162461bcd60e51b815260206004820152600f60248201526e159053155157d513d3d7d4d3505313608a1b6044820152606401611145565b6138e23330836137d461163b565b6138ec8284613d90565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610ed48184613e8e565b600080613947613322565b9050336001600160a01b038516146139bb576001600160a01b0384166000908152600282016020908152604080832033845290915290205460001981146139b957613992878261465b565b6001600160a01b038616600090815260028401602090815260408083203384529091529020555b505b60028701546001600160401b03600160281b909104811690841610156139f757600160405163201f67df60e01b8152600401611145919061462b565b613a00866117fc565b915081600003613a405760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401611145565b613a4861192e565b821015613a685760405163edb7a7ff60e01b815260040160405180910390fd5b6001600160a01b038416600090815260018201602052604081208054889290613a9290849061465b565b909155505030600081815260018301602052604090819020805489019055516001600160a01b0386169060008051602061492083398151915290613ad9908a815260200190565b60405180910390a3613aeb87846130ce565b60408051838152602081018890526001600160a01b03808716929088169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a46001600160401b0383166000908152600688016020526040908190205490516394bf804d60e01b8152600481018890526001600160a01b038781166024830152600160401b909204909116906394bf804d906044016020604051808303816000875af1158015613baa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bce919061466e565b505095945050505050565b600080613bf0600119368181013560f01c90030190565b929092013592915050565b6000610f9a8383670de0b6b3a7640000613304565b6000600160281b821061351e57600080fd5b6000613c2c613322565b6001600160a01b0384166000908152600182016020526040812080549293508492909190613c5b90849061465b565b9091555050805482900381556040518281526000906001600160a01b03851690600080516020614920833981519152906020015b60405180910390a3505050565b600080613cb3600119368181013560f01c90030190565b929092013560f81c92915050565b6000806000613cd08686613f2b565b915091508381836000f592506001600160a01b0383166127b857604051631d7fde3160e31b815260040160405180910390fd5b6001600160401b038181166000818152600685016020908152604091829020805480861660010190951667ffffffffffffffff199095168517905581519283528201929092527fc78e24d95d2fbcef8eeb6cf95914c9a7cfd906a017910a054d2404baac85123191016114f1565b6001600160a01b038216158015906117a9576117a98383611be461163b565b6000613d9a613322565b905081816000016000828254613db09190614687565b90915550506001600160a01b03831660008181526001830160209081526040808320805487019055518581526000805160206149208339815191529101613c8f565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b03841660248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080613e875760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401611145565b5050505050565b6000613e98612f60565b8054840181556005810180548501905590506000613eb461346e565b805490915015801590613ecf57508054613ecc610e36565b10155b15613ef057600860405163201f67df60e01b8152600401611145919061462b565b81546040519081527f0d929f3d1cc26451e13ef120a91a57d7b74aabeb7d27aea8659f79232ded5bb79060200160405180910390a150505050565b8051604051606160f81b81526039820160f081811b60018401526f3d81600a3d39f33d3d3d3d363d3d376160801b600384015260028401901b601383018190526560373639366160d01b6015840152601b83015262013d7360e81b601d830152606085901b6020808401919091526c5af43d3d93803e603557fd5bf360981b603484015291926043810192909190850182604186015b60208210613fe05782518152602092830192601f199092019101613fc1565b915160001960208390036101000a011916825260f09390931b920191909152505b9250929050565b80356001600160401b038116811461401f57600080fd5b919050565b600080600080600060a0868803121561403c57600080fd5b853594506020860135935061405360408701614008565b94979396509394606081013594506080013592915050565b60006020828403121561407d57600080fd5b81356001600160e01b031981168114610f9a57600080fd5b60005b838110156140b0578181015183820152602001614098565b50506000910152565b600081518084526140d1816020860160208601614095565b601f01601f19169290920160200192915050565b602081526000610f9a60208301846140b9565b60006020828403121561410a57600080fd5b5035919050565b6001600160a01b038116811461412657600080fd5b50565b6000806040838503121561413c57600080fd5b823561414781614111565b946020939093013593505050565b60008060008060006080868803121561416d57600080fd5b853561417881614111565b9450602086013561418881614111565b93506040860135925060608601356001600160401b03808211156141ab57600080fd5b818801915088601f8301126141bf57600080fd5b8135818111156141ce57600080fd5b8960208285010111156141e057600080fd5b9699959850939650602001949392505050565b60008060006060848603121561420857600080fd5b833561421381614111565b9250602084013561422381614111565b929592945050506040919091013590565b801515811461412657600080fd5b6000806040838503121561425557600080fd5b823561426081614111565b9150602083013561427081614234565b809150509250929050565b60006020828403121561428d57600080fd5b610f9a82614008565b600060c082840312156142a857600080fd5b50919050565b6000602082840312156142c057600080fd5b8135610f9a81614111565b6000602082840312156142dd57600080fd5b81356001600160401b038111156142f357600080fd5b820160808185031215610f9a57600080fd5b6000806040838503121561431857600080fd5b82359150602083013561427081614111565b6000806000806080858703121561434057600080fd5b84359350602085013561435281614111565b9250604085013561436281614111565b915061437060608601614008565b905092959194509250565b60008060006060848603121561439057600080fd5b8335925060208401356143a281614111565b915060408401356143b281614111565b809150509250925092565b60ff8116811461412657600080fd5b600080600080600080600060e0888a0312156143e757600080fd5b87356143f281614111565b9650602088013561440281614111565b955060408801359450606088013593506080880135614420816143bd565b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561445057600080fd5b823561445b81614111565b9150602083013561427081614111565b60006020828403121561447d57600080fd5b8151610f9a81614111565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906144bb908301846140b9565b9695505050505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156144ed57600080fd5b81516001600160401b038082111561450457600080fd5b818401915084601f83011261451857600080fd5b81518181111561452a5761452a6144c5565b604051601f8201601f19908116603f01168101908382118183101715614552576145526144c5565b8160405282815287602084870101111561456b57600080fd5b61457c836020830160208801614095565b979650505050505050565b694153542d5661756c742d60b01b8152600082516145ac81600a850160208701614095565b91909101600a0192915050565b600080600080600060a086880312156145d157600080fd5b85359450602086013564ffffffffff811681146145ed57600080fd5b935060408601359250606086013561460481614111565b949793965091946080013592915050565b634e487b7160e01b600052602160045260246000fd5b60208101600a831061463f5761463f614615565b91905290565b634e487b7160e01b600052601160045260246000fd5b81810381811115610ed457610ed4614645565b60006020828403121561468057600080fd5b5051919050565b80820180821115610ed457610ed4614645565b6001600160401b038281168282160390808211156146ba576146ba614645565b5092915050565b6000602082840312156146d357600080fd5b8135610f9a81614234565b6000808335601e198436030181126146f557600080fd5b8301803591506001600160401b0382111561470f57600080fd5b6020019150600581901b360382131561400157600080fd5b634e487b7160e01b600052603260045260246000fd5b602081016005831061463f5761463f614615565b60006020828403121561476357600080fd5b8151610f9a816143bd565b60ff8281168282160390811115610ed457610ed4614645565b600181815b808511156147c25781600019048211156147a8576147a8614645565b808516156147b557918102915b93841c939080029061478c565b509250929050565b6000826147d957506001610ed4565b816147e657506000610ed4565b81600181146147fc576002811461480657614822565b6001915050610ed4565b60ff84111561481757614817614645565b50506001821b610ed4565b5060208310610133831016604e8410600b8410161715614845575081810a610ed4565b61484f8383614787565b806000190482111561486357614863614645565b029392505050565b6000610f9a60ff8416836147ca565b60006020828403121561488c57600080fd5b8151610f9a81614234565b654153542d562d60d01b8152600082516148b8816006850160208701614095565b9190910160060192915050565b8082028115828204841417610ed457610ed4614645565b60006001600160401b038216806148f5576148f5614645565b6000190192915050565b6001600160401b038181168382160190808211156146ba576146ba61464556feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212206372e7e3c4d6cc90230cd62e366a1a1c6cd2b6d95796d557e17447032d3d3e6364736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.