More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x2787b4a28817860d6abad2c3c05fceb894686049a63a372baefeeb348d6df830 | Update Atomic Re... | (pending) | 8 days ago | IN | 0 ETH | (Pending) | |||
Update Atomic Re... | 21463622 | 5 mins ago | IN | 0 ETH | 0.0002869 | ||||
Update Atomic Re... | 21463589 | 11 mins ago | IN | 0 ETH | 0.00017027 | ||||
Update Atomic Re... | 21463587 | 12 mins ago | IN | 0 ETH | 0.00026261 | ||||
Update Atomic Re... | 21463581 | 13 mins ago | IN | 0 ETH | 0.00025924 | ||||
Update Atomic Re... | 21463580 | 13 mins ago | IN | 0 ETH | 0.00025321 | ||||
Update Atomic Re... | 21463573 | 14 mins ago | IN | 0 ETH | 0.00015073 | ||||
Update Atomic Re... | 21463564 | 16 mins ago | IN | 0 ETH | 0.00016219 | ||||
Update Atomic Re... | 21463491 | 31 mins ago | IN | 0 ETH | 0.00021624 | ||||
Update Atomic Re... | 21463455 | 38 mins ago | IN | 0 ETH | 0.00027886 | ||||
Update Atomic Re... | 21463414 | 46 mins ago | IN | 0 ETH | 0.00020533 | ||||
Update Atomic Re... | 21463410 | 47 mins ago | IN | 0 ETH | 0.00021672 | ||||
Update Atomic Re... | 21463395 | 50 mins ago | IN | 0 ETH | 0.00016725 | ||||
Update Atomic Re... | 21463395 | 50 mins ago | IN | 0 ETH | 0.00024933 | ||||
Update Atomic Re... | 21463389 | 51 mins ago | IN | 0 ETH | 0.00022621 | ||||
Update Atomic Re... | 21463227 | 1 hr ago | IN | 0 ETH | 0.00013984 | ||||
Update Atomic Re... | 21463198 | 1 hr ago | IN | 0 ETH | 0.00018956 | ||||
Update Atomic Re... | 21463198 | 1 hr ago | IN | 0 ETH | 0.00012733 | ||||
Update Atomic Re... | 21463196 | 1 hr ago | IN | 0 ETH | 0.00024057 | ||||
Update Atomic Re... | 21463185 | 1 hr ago | IN | 0 ETH | 0.00023611 | ||||
Update Atomic Re... | 21463145 | 1 hr ago | IN | 0 ETH | 0.00017168 | ||||
Update Atomic Re... | 21463140 | 1 hr ago | IN | 0 ETH | 0.00022064 | ||||
Update Atomic Re... | 21463135 | 1 hr ago | IN | 0 ETH | 0.00023366 | ||||
Update Atomic Re... | 21463125 | 1 hr ago | IN | 0 ETH | 0.00025199 | ||||
Update Atomic Re... | 21463115 | 1 hr ago | IN | 0 ETH | 0.00023719 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
AtomicQueue
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.21; import { Math } from "src/utils/Math.sol"; import { SafeTransferLib } from "@solmate/utils/SafeTransferLib.sol"; import { ERC20 } from "@solmate/tokens/ERC20.sol"; import { ReentrancyGuard } from "@solmate/utils/ReentrancyGuard.sol"; import { IAtomicSolver } from "./IAtomicSolver.sol"; /** * @title AtomicQueue * @notice Allows users to create `AtomicRequests` that specify an ERC20 asset to `offer` * and an ERC20 asset to `want` in return. * @notice Making atomic requests where the exchange rate between offer and want is not * relatively stable is effectively the same as placing a limit order between * those assets, so requests can be filled at a rate worse than the current market rate. * @notice It is possible for a user to make multiple requests that use the same offer asset. * If this is done it is important that the user has approved the queue to spend the * total amount of assets aggregated from all their requests, and to also have enough * `offer` asset to cover the aggregate total request of `offerAmount`. * @author crispymangoes */ contract AtomicQueue is ReentrancyGuard { using SafeTransferLib for ERC20; using Math for uint256; // ========================================= STRUCTS ========================================= /** * @notice Stores request information needed to fulfill a users atomic request. * @param deadline unix timestamp for when request is no longer valid * @param atomicPrice the price in terms of `want` asset the user wants their `offer` assets "sold" at * @dev atomicPrice MUST be in terms of `want` asset decimals. * @param offerAmount the amount of `offer` asset the user wants converted to `want` asset * @param inSolve bool used during solves to prevent duplicate users, and to prevent redoing multiple checks */ struct AtomicRequest { uint64 deadline; // deadline to fulfill request uint88 atomicPrice; // In terms of want asset decimals uint96 offerAmount; // The amount of offer asset the user wants to sell. bool inSolve; // Indicates whether this user is currently having their request fulfilled. } /** * @notice Used in `viewSolveMetaData` helper function to return data in a clean struct. * @param user the address of the user * @param flags 8 bits indicating the state of the user only the first 4 bits are used XXXX0000 * Either all flags are false(user is solvable) or only 1 is true(an error occurred). * From right to left * - 0: indicates user deadline has passed. * - 1: indicates user request has zero offer amount. * - 2: indicates user does not have enough offer asset in wallet. * - 3: indicates user has not given AtomicQueue approval. * @param assetsToOffer the amount of offer asset to solve * @param assetsForWant the amount of assets users want for their offer assets */ struct SolveMetaData { address user; uint8 flags; uint256 assetsToOffer; uint256 assetsForWant; } // ========================================= GLOBAL STATE ========================================= /** * @notice Maps user address to offer asset to want asset to a AtomicRequest struct. */ mapping(address => mapping(ERC20 => mapping(ERC20 => AtomicRequest))) public userAtomicRequest; //============================== ERRORS =============================== error AtomicQueue__UserRepeated(address user); error AtomicQueue__RequestDeadlineExceeded(address user); error AtomicQueue__UserNotInSolve(address user); error AtomicQueue__ZeroOfferAmount(address user); //============================== EVENTS =============================== /** * @notice Emitted when `updateAtomicRequest` is called. */ event AtomicRequestUpdated( address user, address offerToken, address wantToken, uint256 amount, uint256 deadline, uint256 minPrice, uint256 timestamp ); /** * @notice Emitted when `solve` exchanges a users offer asset for their want asset. */ event AtomicRequestFulfilled( address user, address offerToken, address wantToken, uint256 offerAmountSpent, uint256 wantAmountReceived, uint256 timestamp ); //============================== USER FUNCTIONS =============================== /** * @notice Get a users Atomic Request. * @param user the address of the user to get the request for * @param offer the ERC0 token they want to exchange for the want * @param want the ERC20 token they want in exchange for the offer */ function getUserAtomicRequest(address user, ERC20 offer, ERC20 want) external view returns (AtomicRequest memory) { return userAtomicRequest[user][offer][want]; } /** * @notice Helper function that returns either * true: Withdraw request is valid. * false: Withdraw request is not valid. * @dev It is possible for a withdraw request to return false from this function, but using the * request in `updateAtomicRequest` will succeed, but solvers will not be able to include * the user in `solve` unless some other state is changed. * @param offer the ERC0 token they want to exchange for the want * @param user the address of the user making the request * @param userRequest the request struct to validate */ function isAtomicRequestValid( ERC20 offer, address user, AtomicRequest calldata userRequest ) external view returns (bool) { // Validate amount. if (userRequest.offerAmount > offer.balanceOf(user)) return false; // Validate deadline. if (block.timestamp > userRequest.deadline) return false; // Validate approval. if (offer.allowance(user, address(this)) < userRequest.offerAmount) return false; // Validate offerAmount is nonzero. if (userRequest.offerAmount == 0) return false; // Validate atomicPrice is nonzero. if (userRequest.atomicPrice == 0) return false; return true; } /** * @notice Allows user to add/update their withdraw request. * @notice It is possible for a withdraw request with a zero atomicPrice to be made, and solved. * If this happens, users will be selling their shares for no assets in return. * To determine a safe atomicPrice, share.previewRedeem should be used to get * a good share price, then the user can lower it from there to make their request fill faster. * @param offer the ERC20 token the user is offering in exchange for the want * @param want the ERC20 token the user wants in exchange for offer * @param userRequest the users request */ function updateAtomicRequest(ERC20 offer, ERC20 want, AtomicRequest calldata userRequest) external nonReentrant { AtomicRequest storage request = userAtomicRequest[msg.sender][offer][want]; request.deadline = userRequest.deadline; request.atomicPrice = userRequest.atomicPrice; request.offerAmount = userRequest.offerAmount; // Emit full amount user has. emit AtomicRequestUpdated( msg.sender, address(offer), address(want), userRequest.offerAmount, userRequest.deadline, userRequest.atomicPrice, block.timestamp ); } //============================== SOLVER FUNCTIONS =============================== /** * @notice Called by solvers in order to exchange offer asset for want asset. * @notice Solvers are optimistically transferred the offer asset, then are required to * approve this contract to spend enough of want assets to cover all requests. * @dev It is very likely `solve` TXs will be front run if broadcasted to public mem pools, * so solvers should use private mem pools. * @param offer the ERC20 offer token to solve for * @param want the ERC20 want token to solve for * @param users an array of user addresses to solve for * @param runData extra data that is passed back to solver when `finishSolve` is called * @param solver the address to make `finishSolve` callback to */ function solve( ERC20 offer, ERC20 want, address[] calldata users, bytes calldata runData, address solver ) external nonReentrant { // Save offer asset decimals. uint8 offerDecimals = offer.decimals(); uint256 assetsToOffer; uint256 assetsForWant; for (uint256 i; i < users.length; ++i) { AtomicRequest storage request = userAtomicRequest[users[i]][offer][want]; if (request.inSolve) revert AtomicQueue__UserRepeated(users[i]); if (block.timestamp > request.deadline) revert AtomicQueue__RequestDeadlineExceeded(users[i]); if (request.offerAmount == 0) revert AtomicQueue__ZeroOfferAmount(users[i]); // User gets whatever their atomic price * offerAmount is. assetsForWant += _calculateAssetAmount(request.offerAmount, request.atomicPrice, offerDecimals); // If all checks above passed, the users request is valid and should be fulfilled. assetsToOffer += request.offerAmount; request.inSolve = true; // Transfer shares from user to solver. offer.safeTransferFrom(users[i], solver, request.offerAmount); } IAtomicSolver(solver).finishSolve(runData, msg.sender, offer, want, assetsToOffer, assetsForWant); for (uint256 i; i < users.length; ++i) { AtomicRequest storage request = userAtomicRequest[users[i]][offer][want]; if (request.inSolve) { // We know that the minimum price and deadline arguments are satisfied since this can only be true if they were. // Send user their share of assets. uint256 assetsToUser = _calculateAssetAmount(request.offerAmount, request.atomicPrice, offerDecimals); want.safeTransferFrom(solver, users[i], assetsToUser); emit AtomicRequestFulfilled( users[i], address(offer), address(want), request.offerAmount, assetsToUser, block.timestamp ); // Set shares to withdraw to 0. request.offerAmount = 0; request.inSolve = false; } else revert AtomicQueue__UserNotInSolve(users[i]); } } /** * @notice Helper function solvers can use to determine if users are solvable, and the required amounts to do so. * @notice Repeated users are not accounted for in this setup, so if solvers have repeat users in their `users` * array the results can be wrong. * @dev Since a user can have multiple requests with the same offer asset but different want asset, it is * possible for `viewSolveMetaData` to report no errors, but for a solve to fail, if any solves were done * between the time `viewSolveMetaData` and before `solve` is called. * @param offer the ERC20 offer token to check for solvability * @param want the ERC20 want token to check for solvability * @param users an array of user addresses to check for solvability */ function viewSolveMetaData( ERC20 offer, ERC20 want, address[] calldata users ) external view returns (SolveMetaData[] memory metaData, uint256 totalAssetsForWant, uint256 totalAssetsToOffer) { // Save offer asset decimals. uint8 offerDecimals = offer.decimals(); // Setup meta data. metaData = new SolveMetaData[](users.length); for (uint256 i; i < users.length; ++i) { AtomicRequest memory request = userAtomicRequest[users[i]][offer][want]; metaData[i].user = users[i]; if (block.timestamp > request.deadline) { metaData[i].flags |= uint8(1); } if (request.offerAmount == 0) { metaData[i].flags |= uint8(1) << 1; } if (offer.balanceOf(users[i]) < request.offerAmount) { metaData[i].flags |= uint8(1) << 2; } if (offer.allowance(users[i], address(this)) < request.offerAmount) { metaData[i].flags |= uint8(1) << 3; } metaData[i].assetsToOffer = request.offerAmount; // User gets whatever their execution share price is. uint256 userAssets = _calculateAssetAmount(request.offerAmount, request.atomicPrice, offerDecimals); metaData[i].assetsForWant = userAssets; // If flags is zero, no errors occurred. if (metaData[i].flags == 0) { totalAssetsForWant += userAssets; totalAssetsToOffer += request.offerAmount; } } } //============================== INTERNAL FUNCTIONS =============================== /** * @notice Helper function to calculate the amount of want assets a users wants in exchange for * `offerAmount` of offer asset. */ function _calculateAssetAmount( uint256 offerAmount, uint256 atomicPrice, uint8 offerDecimals ) internal pure returns (uint256) { return atomicPrice.mulDivDown(offerAmount, 10 ** offerDecimals); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.21; library Math { /** * @notice Substract with a floor of 0 for the result. */ function subMinZero(uint256 x, uint256 y) internal pure returns (uint256) { return x > y ? x - y : 0; } /** * @notice Used to change the decimals of precision used for an amount. */ function changeDecimals(uint256 amount, uint8 fromDecimals, uint8 toDecimals) internal pure returns (uint256) { if (fromDecimals == toDecimals) { return amount; } else if (fromDecimals < toDecimals) { return amount * 10 ** (toDecimals - fromDecimals); } else { return amount / 10 ** (fromDecimals - toDecimals); } } // ===================================== OPENZEPPELIN'S MATH ===================================== function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } // ================================= SOLMATE's FIXEDPOINTMATHLIB ================================= uint256 public 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 mulDivDown(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // Divide z by the denominator. z := div(z, denominator) } } function mulDivUp(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // First, divide z - 1 by the denominator and add 1. // We allow z - 1 to underflow if z is 0, because we multiply the // end result by 0 if z is zero, ensuring we return 0 if z is zero. z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1)) } } }
// 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), from) // Append the "from" argument. mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. 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), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. 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), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. 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 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; /// @notice Gas optimized reentrancy protection for smart contracts. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) abstract contract ReentrancyGuard { uint256 private locked = 1; modifier nonReentrant() virtual { require(locked == 1, "REENTRANCY"); locked = 2; _; locked = 1; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; import { ERC20 } from "@solmate/tokens/ERC20.sol"; interface IAtomicSolver { /** * @notice This function must be implemented in order for an address to be a `solver` * for the AtomicQueue * @param runData arbitrary bytes data that is dependent on how each solver is setup * it could contain swap data, or flash loan data, etc.. * @param initiator the address that initiated a solve * @param offer the ERC20 asset sent to the solver * @param want the ERC20 asset the solver must approve the queue for * @param assetsToOffer the amount of `offer` sent to the solver * @param assetsForWant the amount of `want` the solver must approve the queue for */ function finishSolve( bytes calldata runData, address initiator, ERC20 offer, ERC20 want, uint256 assetsToOffer, uint256 assetsForWant ) external; }
{ "remappings": [ "@solmate/=lib/solmate/src/", "@forge-std/=lib/forge-std/src/", "@ds-test/=lib/forge-std/lib/ds-test/src/", "ds-test/=lib/forge-std/lib/ds-test/src/", "@openzeppelin/=lib/openzeppelin-contracts/", "@uniswap/v3-periphery/=lib/v3-periphery/", "@uniswap/v3-core/=lib/v3-core/", "@chainlink/=lib/chainlink/", "@uniswapV3P/=lib/v3-periphery/contracts/", "@uniswapV3C/=lib/v3-core/contracts/", "@balancer/=lib/balancer-v2-monorepo/pkg/", "@ccip/=lib/ccip/", "@pendle/=lib/pendle-core-v2-public/", "@balancer-labs/=lib/balancer-v2-monorepo/../../node_modules/@balancer-labs/", "axelar-gmp-sdk-solidity/=lib/axelar-gmp-sdk-solidity/contracts/", "balancer-v2-monorepo/=lib/balancer-v2-monorepo/", "ccip/=lib/ccip/contracts/", "chainlink/=lib/chainlink/integration-tests/contracts/ethereum/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "pendle-core-v2-public/=lib/pendle-core-v2-public/contracts/", "solmate/=lib/solmate/src/", "v3-core/=lib/v3-core/contracts/", "v3-periphery/=lib/v3-periphery/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "shanghai", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"AtomicQueue__RequestDeadlineExceeded","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"AtomicQueue__UserNotInSolve","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"AtomicQueue__UserRepeated","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"AtomicQueue__ZeroOfferAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"offerToken","type":"address"},{"indexed":false,"internalType":"address","name":"wantToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"offerAmountSpent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wantAmountReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AtomicRequestFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"offerToken","type":"address"},{"indexed":false,"internalType":"address","name":"wantToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AtomicRequestUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"contract ERC20","name":"offer","type":"address"},{"internalType":"contract ERC20","name":"want","type":"address"}],"name":"getUserAtomicRequest","outputs":[{"components":[{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint88","name":"atomicPrice","type":"uint88"},{"internalType":"uint96","name":"offerAmount","type":"uint96"},{"internalType":"bool","name":"inSolve","type":"bool"}],"internalType":"struct AtomicQueue.AtomicRequest","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"offer","type":"address"},{"internalType":"address","name":"user","type":"address"},{"components":[{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint88","name":"atomicPrice","type":"uint88"},{"internalType":"uint96","name":"offerAmount","type":"uint96"},{"internalType":"bool","name":"inSolve","type":"bool"}],"internalType":"struct AtomicQueue.AtomicRequest","name":"userRequest","type":"tuple"}],"name":"isAtomicRequestValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"offer","type":"address"},{"internalType":"contract ERC20","name":"want","type":"address"},{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"bytes","name":"runData","type":"bytes"},{"internalType":"address","name":"solver","type":"address"}],"name":"solve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"offer","type":"address"},{"internalType":"contract ERC20","name":"want","type":"address"},{"components":[{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint88","name":"atomicPrice","type":"uint88"},{"internalType":"uint96","name":"offerAmount","type":"uint96"},{"internalType":"bool","name":"inSolve","type":"bool"}],"internalType":"struct AtomicQueue.AtomicRequest","name":"userRequest","type":"tuple"}],"name":"updateAtomicRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"contract ERC20","name":"","type":"address"},{"internalType":"contract ERC20","name":"","type":"address"}],"name":"userAtomicRequest","outputs":[{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint88","name":"atomicPrice","type":"uint88"},{"internalType":"uint96","name":"offerAmount","type":"uint96"},{"internalType":"bool","name":"inSolve","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"offer","type":"address"},{"internalType":"contract ERC20","name":"want","type":"address"},{"internalType":"address[]","name":"users","type":"address[]"}],"name":"viewSolveMetaData","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint8","name":"flags","type":"uint8"},{"internalType":"uint256","name":"assetsToOffer","type":"uint256"},{"internalType":"uint256","name":"assetsForWant","type":"uint256"}],"internalType":"struct AtomicQueue.SolveMetaData[]","name":"metaData","type":"tuple[]"},{"internalType":"uint256","name":"totalAssetsForWant","type":"uint256"},{"internalType":"uint256","name":"totalAssetsToOffer","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260015f55348015610013575f80fd5b50611738806100215f395ff3fe608060405234801561000f575f80fd5b5060043610610060575f3560e01c80632788dd94146100645780632ae2f0711461008c578063433a8534146100ae5780637abf631d146101b35780637c88eaa11461025c578063d93fc20314610271575b5f80fd5b610077610072366004611210565b610284565b60405190151581526020015b60405180910390f35b61009f61009a36600461129c565b610428565b604051610083939291906112fc565b6101636100bc366004611378565b60408051608080820183525f808352602080840182905283850182905260609384018290526001600160a01b0397881682526001815284822096881682529586528381209490961686529284529381902081519283018252546001600160401b0381168352600160401b81046001600160581b031693830193909352600160981b83046001600160601b031690820152600160f81b90910460ff1615159181019190915290565b604051610083919081516001600160401b031681526020808301516001600160581b0316908201526040808301516001600160601b03169082015260609182015115159181019190915260800190565b61021a6101c1366004611378565b600160209081525f93845260408085208252928452828420905282529020546001600160401b03811690600160401b81046001600160581b031690600160981b81046001600160601b031690600160f81b900460ff1684565b604080516001600160401b0390951685526001600160581b0390931660208501526001600160601b039091169183019190915215156060820152608001610083565b61026f61026a366004611210565b61093e565b005b61026f61027f3660046113c0565b610b12565b6040516370a0823160e01b81526001600160a01b0383811660048301525f91908516906370a0823190602401602060405180830381865afa1580156102cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102ef9190611488565b6102ff606084016040850161149f565b6001600160601b0316111561031557505f610421565b61032260208301836114c5565b6001600160401b031642111561033957505f610421565b610349606083016040840161149f565b604051636eb1769f60e11b81526001600160a01b0385811660048301523060248301526001600160601b03929092169186169063dd62ed3e90604401602060405180830381865afa1580156103a0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103c49190611488565b10156103d157505f610421565b6103e1606083016040840161149f565b6001600160601b03165f036103f757505f610421565b61040760408301602084016114eb565b6001600160581b03165f0361041d57505f610421565b5060015b9392505050565b60605f805f876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610469573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061048d9190611511565b9050846001600160401b038111156104a7576104a7611531565b6040519080825280602002602001820160405280156104f757816020015b604080516080810182525f8082526020808301829052928201819052606082015282525f199092019101816104c55790505b5093505f5b85811015610932575f60015f89898581811061051a5761051a611545565b905060200201602081019061052f9190611559565b6001600160a01b03908116825260208083019390935260409182015f9081208e831682528452828120918d168152908352819020815160808101835290546001600160401b0381168252600160401b81046001600160581b031693820193909352600160981b83046001600160601b031691810191909152600160f81b90910460ff161515606082015290508787838181106105cd576105cd611545565b90506020020160208101906105e29190611559565b8683815181106105f4576105f4611545565b60209081029190910101516001600160a01b03909116905280516001600160401b031642111561064b57600186838151811061063257610632611545565b6020908102919091018101510180519190911760ff1690525b80604001516001600160601b03165f0361068f57855160029087908490811061067657610676611545565b6020908102919091018101510180519190911760ff1690525b80604001516001600160601b03168a6001600160a01b03166370a082318a8a868181106106be576106be611545565b90506020020160208101906106d39190611559565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610715573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107399190611488565b101561076f57855160049087908490811061075657610756611545565b6020908102919091018101510180519190911760ff1690525b80604001516001600160601b03168a6001600160a01b031663dd62ed3e8a8a8681811061079e5761079e611545565b90506020020160208101906107b39190611559565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa1580156107fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061081f9190611488565b101561085557855160089087908490811061083c5761083c611545565b6020908102919091018101510180519190911760ff1690525b80604001516001600160601b031686838151811061087557610875611545565b602002602001015160400181815250505f6108ab82604001516001600160601b031683602001516001600160581b03168661110f565b9050808784815181106108c0576108c0611545565b602002602001015160600181815250508683815181106108e2576108e2611545565b60200260200101516020015160ff165f0361091f576109018187611588565b955081604001516001600160601b03168561091c9190611588565b94505b50508061092b906115a1565b90506104fc565b50509450945094915050565b5f546001146109815760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b60025f9081553381526001602090815260408083206001600160a01b03878116855290835281842090861684528252909120906109c0908301836114c5565b815467ffffffffffffffff19166001600160401b03919091161781556109ec60408301602084016114eb565b81546001600160581b0391909116600160401b0272ffffffffffffffffffffff000000000000000019909116178155610a2b606083016040840161149f565b81546001600160601b0391909116600160981b026bffffffffffffffffffffffff60981b199091161781557f9537495a2390e1a29f5f7e71b8540f5140bba27065f173615b770ad79d2f7960338585610a8a606087016040880161149f565b610a9760208801886114c5565b610aa76040890160208a016114eb565b604080516001600160a01b039788168152958716602087015293909516928401929092526001600160601b031660608301526001600160401b031660808201526001600160581b0390911660a08201524260c082015260e00160405180910390a1505060015f555050565b5f54600114610b505760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610978565b60025f819055505f876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b94573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb89190611511565b90505f805f5b87811015610e46575f60015f8b8b85818110610bdc57610bdc611545565b9050602002016020810190610bf19190611559565b6001600160a01b03166001600160a01b031681526020019081526020015f205f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8c6001600160a01b03166001600160a01b031681526020019081526020015f209050805f01601f9054906101000a900460ff1615610cb957898983818110610c7c57610c7c611545565b9050602002016020810190610c919190611559565b6040516001627c10bd60e11b031981526001600160a01b039091166004820152602401610978565b80546001600160401b0316421115610d1757898983818110610cdd57610cdd611545565b9050602002016020810190610cf29190611559565b6040516342a646e960e01b81526001600160a01b039091166004820152602401610978565b8054600160981b90046001600160601b03165f03610d7b57898983818110610d4157610d41611545565b9050602002016020810190610d569190611559565b60405163aeb7e20360e01b81526001600160a01b039091166004820152602401610978565b8054610da890600160981b81046001600160601b031690600160401b90046001600160581b03168761110f565b610db29084611588565b8154909350610dd190600160981b90046001600160601b031685611588565b81546001600160f81b0316600160f81b1782559350610e358a8a84818110610dfb57610dfb611545565b9050602002016020810190610e109190611559565b82546001600160a01b038f1691908990600160981b90046001600160601b031661112f565b50610e3f816115a1565b9050610bbe565b50836001600160a01b0316632ddd62ce8787338e8e88886040518863ffffffff1660e01b8152600401610e7f97969594939291906115b9565b5f604051808303815f87803b158015610e96575f80fd5b505af1158015610ea8573d5f803e3d5ffd5b505050505f5b878110156110fe575f60015f8b8b85818110610ecc57610ecc611545565b9050602002016020810190610ee19190611559565b6001600160a01b03166001600160a01b031681526020019081526020015f205f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8c6001600160a01b03166001600160a01b031681526020019081526020015f209050805f01601f9054906101000a900460ff16156110a15780545f90610f8990600160981b81046001600160601b031690600160401b90046001600160581b03168861110f565b9050610fc8878c8c86818110610fa157610fa1611545565b9050602002016020810190610fb69190611559565b6001600160a01b038f1691908461112f565b7fa4e3f90ef19273220b37cbbbcfe402a6eadd9559c54813b9be52ea0c9612d6c98b8b85818110610ffb57610ffb611545565b90506020020160208101906110109190611559565b8e8e855f0160139054906101000a90046001600160601b0316854260405161107a969594939291906001600160a01b03968716815294861660208601529290941660408401526001600160601b03166060830152608082019290925260a081019190915260c00190565b60405180910390a150805472ffffffffffffffffffffffffffffffffffffff1681556110ed565b8989838181106110b3576110b3611545565b90506020020160208101906110c89190611559565b60405163d698186360e01b81526001600160a01b039091166004820152602401610978565b506110f7816115a1565b9050610eae565b505060015f55505050505050505050565b5f6111278461111f84600a6116f4565b8591906111b5565b949350505050565b5f6040516323b872dd60e01b815284600482015283602482015282604482015260205f6064835f8a5af13d15601f3d1160015f5114161716915050806111ae5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610978565b5050505050565b8282028115158415858304851417166111cc575f80fd5b0492915050565b6001600160a01b03811681146111e7575f80fd5b50565b80356111f5816111d3565b919050565b5f6080828403121561120a575f80fd5b50919050565b5f805f60c08486031215611222575f80fd5b833561122d816111d3565b9250602084013561123d816111d3565b915061124c85604086016111fa565b90509250925092565b5f8083601f840112611265575f80fd5b5081356001600160401b0381111561127b575f80fd5b6020830191508360208260051b8501011115611295575f80fd5b9250929050565b5f805f80606085870312156112af575f80fd5b84356112ba816111d3565b935060208501356112ca816111d3565b925060408501356001600160401b038111156112e4575f80fd5b6112f087828801611255565b95989497509550505050565b606080825284518282018190525f9190608090818501906020808a01865b8381101561135d57815180516001600160a01b031686528381015160ff16848701526040808201519087015287015187860152938501939082019060010161131a565b50508601979097526040909401949094525090949350505050565b5f805f6060848603121561138a575f80fd5b8335611395816111d3565b925060208401356113a5816111d3565b915060408401356113b5816111d3565b809150509250925092565b5f805f805f805f60a0888a0312156113d6575f80fd5b87356113e1816111d3565b965060208801356113f1816111d3565b955060408801356001600160401b038082111561140c575f80fd5b6114188b838c01611255565b909750955060608a0135915080821115611430575f80fd5b818a0191508a601f830112611443575f80fd5b813581811115611451575f80fd5b8b6020828501011115611462575f80fd5b60208301955080945050505061147a608089016111ea565b905092959891949750929550565b5f60208284031215611498575f80fd5b5051919050565b5f602082840312156114af575f80fd5b81356001600160601b0381168114610421575f80fd5b5f602082840312156114d5575f80fd5b81356001600160401b0381168114610421575f80fd5b5f602082840312156114fb575f80fd5b81356001600160581b0381168114610421575f80fd5b5f60208284031215611521575f80fd5b815160ff81168114610421575f80fd5b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215611569575f80fd5b8135610421816111d3565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561159b5761159b611574565b92915050565b5f600182016115b2576115b2611574565b5060010190565b60c081528660c0820152868860e08301375f60e08883018101919091526001600160a01b0396871660208301529486166040820152929094166060830152608082015260a0810192909252601f909201601f19160101919050565b600181815b8085111561164e57815f190482111561163457611634611574565b8085161561164157918102915b93841c9390800290611619565b509250929050565b5f826116645750600161159b565b8161167057505f61159b565b81600181146116865760028114611690576116ac565b600191505061159b565b60ff8411156116a1576116a1611574565b50506001821b61159b565b5060208310610133831016604e8410600b84101617156116cf575081810a61159b565b6116d98383611614565b805f19048211156116ec576116ec611574565b029392505050565b5f61042160ff84168361165656fea2646970667358221220ac2f73a8a42fb656e037faafe3f9cd5da4f8716016daabc5646a90ab4183ca4464736f6c63430008150033
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610060575f3560e01c80632788dd94146100645780632ae2f0711461008c578063433a8534146100ae5780637abf631d146101b35780637c88eaa11461025c578063d93fc20314610271575b5f80fd5b610077610072366004611210565b610284565b60405190151581526020015b60405180910390f35b61009f61009a36600461129c565b610428565b604051610083939291906112fc565b6101636100bc366004611378565b60408051608080820183525f808352602080840182905283850182905260609384018290526001600160a01b0397881682526001815284822096881682529586528381209490961686529284529381902081519283018252546001600160401b0381168352600160401b81046001600160581b031693830193909352600160981b83046001600160601b031690820152600160f81b90910460ff1615159181019190915290565b604051610083919081516001600160401b031681526020808301516001600160581b0316908201526040808301516001600160601b03169082015260609182015115159181019190915260800190565b61021a6101c1366004611378565b600160209081525f93845260408085208252928452828420905282529020546001600160401b03811690600160401b81046001600160581b031690600160981b81046001600160601b031690600160f81b900460ff1684565b604080516001600160401b0390951685526001600160581b0390931660208501526001600160601b039091169183019190915215156060820152608001610083565b61026f61026a366004611210565b61093e565b005b61026f61027f3660046113c0565b610b12565b6040516370a0823160e01b81526001600160a01b0383811660048301525f91908516906370a0823190602401602060405180830381865afa1580156102cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102ef9190611488565b6102ff606084016040850161149f565b6001600160601b0316111561031557505f610421565b61032260208301836114c5565b6001600160401b031642111561033957505f610421565b610349606083016040840161149f565b604051636eb1769f60e11b81526001600160a01b0385811660048301523060248301526001600160601b03929092169186169063dd62ed3e90604401602060405180830381865afa1580156103a0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103c49190611488565b10156103d157505f610421565b6103e1606083016040840161149f565b6001600160601b03165f036103f757505f610421565b61040760408301602084016114eb565b6001600160581b03165f0361041d57505f610421565b5060015b9392505050565b60605f805f876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610469573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061048d9190611511565b9050846001600160401b038111156104a7576104a7611531565b6040519080825280602002602001820160405280156104f757816020015b604080516080810182525f8082526020808301829052928201819052606082015282525f199092019101816104c55790505b5093505f5b85811015610932575f60015f89898581811061051a5761051a611545565b905060200201602081019061052f9190611559565b6001600160a01b03908116825260208083019390935260409182015f9081208e831682528452828120918d168152908352819020815160808101835290546001600160401b0381168252600160401b81046001600160581b031693820193909352600160981b83046001600160601b031691810191909152600160f81b90910460ff161515606082015290508787838181106105cd576105cd611545565b90506020020160208101906105e29190611559565b8683815181106105f4576105f4611545565b60209081029190910101516001600160a01b03909116905280516001600160401b031642111561064b57600186838151811061063257610632611545565b6020908102919091018101510180519190911760ff1690525b80604001516001600160601b03165f0361068f57855160029087908490811061067657610676611545565b6020908102919091018101510180519190911760ff1690525b80604001516001600160601b03168a6001600160a01b03166370a082318a8a868181106106be576106be611545565b90506020020160208101906106d39190611559565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610715573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107399190611488565b101561076f57855160049087908490811061075657610756611545565b6020908102919091018101510180519190911760ff1690525b80604001516001600160601b03168a6001600160a01b031663dd62ed3e8a8a8681811061079e5761079e611545565b90506020020160208101906107b39190611559565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa1580156107fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061081f9190611488565b101561085557855160089087908490811061083c5761083c611545565b6020908102919091018101510180519190911760ff1690525b80604001516001600160601b031686838151811061087557610875611545565b602002602001015160400181815250505f6108ab82604001516001600160601b031683602001516001600160581b03168661110f565b9050808784815181106108c0576108c0611545565b602002602001015160600181815250508683815181106108e2576108e2611545565b60200260200101516020015160ff165f0361091f576109018187611588565b955081604001516001600160601b03168561091c9190611588565b94505b50508061092b906115a1565b90506104fc565b50509450945094915050565b5f546001146109815760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b60025f9081553381526001602090815260408083206001600160a01b03878116855290835281842090861684528252909120906109c0908301836114c5565b815467ffffffffffffffff19166001600160401b03919091161781556109ec60408301602084016114eb565b81546001600160581b0391909116600160401b0272ffffffffffffffffffffff000000000000000019909116178155610a2b606083016040840161149f565b81546001600160601b0391909116600160981b026bffffffffffffffffffffffff60981b199091161781557f9537495a2390e1a29f5f7e71b8540f5140bba27065f173615b770ad79d2f7960338585610a8a606087016040880161149f565b610a9760208801886114c5565b610aa76040890160208a016114eb565b604080516001600160a01b039788168152958716602087015293909516928401929092526001600160601b031660608301526001600160401b031660808201526001600160581b0390911660a08201524260c082015260e00160405180910390a1505060015f555050565b5f54600114610b505760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610978565b60025f819055505f876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b94573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb89190611511565b90505f805f5b87811015610e46575f60015f8b8b85818110610bdc57610bdc611545565b9050602002016020810190610bf19190611559565b6001600160a01b03166001600160a01b031681526020019081526020015f205f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8c6001600160a01b03166001600160a01b031681526020019081526020015f209050805f01601f9054906101000a900460ff1615610cb957898983818110610c7c57610c7c611545565b9050602002016020810190610c919190611559565b6040516001627c10bd60e11b031981526001600160a01b039091166004820152602401610978565b80546001600160401b0316421115610d1757898983818110610cdd57610cdd611545565b9050602002016020810190610cf29190611559565b6040516342a646e960e01b81526001600160a01b039091166004820152602401610978565b8054600160981b90046001600160601b03165f03610d7b57898983818110610d4157610d41611545565b9050602002016020810190610d569190611559565b60405163aeb7e20360e01b81526001600160a01b039091166004820152602401610978565b8054610da890600160981b81046001600160601b031690600160401b90046001600160581b03168761110f565b610db29084611588565b8154909350610dd190600160981b90046001600160601b031685611588565b81546001600160f81b0316600160f81b1782559350610e358a8a84818110610dfb57610dfb611545565b9050602002016020810190610e109190611559565b82546001600160a01b038f1691908990600160981b90046001600160601b031661112f565b50610e3f816115a1565b9050610bbe565b50836001600160a01b0316632ddd62ce8787338e8e88886040518863ffffffff1660e01b8152600401610e7f97969594939291906115b9565b5f604051808303815f87803b158015610e96575f80fd5b505af1158015610ea8573d5f803e3d5ffd5b505050505f5b878110156110fe575f60015f8b8b85818110610ecc57610ecc611545565b9050602002016020810190610ee19190611559565b6001600160a01b03166001600160a01b031681526020019081526020015f205f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8c6001600160a01b03166001600160a01b031681526020019081526020015f209050805f01601f9054906101000a900460ff16156110a15780545f90610f8990600160981b81046001600160601b031690600160401b90046001600160581b03168861110f565b9050610fc8878c8c86818110610fa157610fa1611545565b9050602002016020810190610fb69190611559565b6001600160a01b038f1691908461112f565b7fa4e3f90ef19273220b37cbbbcfe402a6eadd9559c54813b9be52ea0c9612d6c98b8b85818110610ffb57610ffb611545565b90506020020160208101906110109190611559565b8e8e855f0160139054906101000a90046001600160601b0316854260405161107a969594939291906001600160a01b03968716815294861660208601529290941660408401526001600160601b03166060830152608082019290925260a081019190915260c00190565b60405180910390a150805472ffffffffffffffffffffffffffffffffffffff1681556110ed565b8989838181106110b3576110b3611545565b90506020020160208101906110c89190611559565b60405163d698186360e01b81526001600160a01b039091166004820152602401610978565b506110f7816115a1565b9050610eae565b505060015f55505050505050505050565b5f6111278461111f84600a6116f4565b8591906111b5565b949350505050565b5f6040516323b872dd60e01b815284600482015283602482015282604482015260205f6064835f8a5af13d15601f3d1160015f5114161716915050806111ae5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610978565b5050505050565b8282028115158415858304851417166111cc575f80fd5b0492915050565b6001600160a01b03811681146111e7575f80fd5b50565b80356111f5816111d3565b919050565b5f6080828403121561120a575f80fd5b50919050565b5f805f60c08486031215611222575f80fd5b833561122d816111d3565b9250602084013561123d816111d3565b915061124c85604086016111fa565b90509250925092565b5f8083601f840112611265575f80fd5b5081356001600160401b0381111561127b575f80fd5b6020830191508360208260051b8501011115611295575f80fd5b9250929050565b5f805f80606085870312156112af575f80fd5b84356112ba816111d3565b935060208501356112ca816111d3565b925060408501356001600160401b038111156112e4575f80fd5b6112f087828801611255565b95989497509550505050565b606080825284518282018190525f9190608090818501906020808a01865b8381101561135d57815180516001600160a01b031686528381015160ff16848701526040808201519087015287015187860152938501939082019060010161131a565b50508601979097526040909401949094525090949350505050565b5f805f6060848603121561138a575f80fd5b8335611395816111d3565b925060208401356113a5816111d3565b915060408401356113b5816111d3565b809150509250925092565b5f805f805f805f60a0888a0312156113d6575f80fd5b87356113e1816111d3565b965060208801356113f1816111d3565b955060408801356001600160401b038082111561140c575f80fd5b6114188b838c01611255565b909750955060608a0135915080821115611430575f80fd5b818a0191508a601f830112611443575f80fd5b813581811115611451575f80fd5b8b6020828501011115611462575f80fd5b60208301955080945050505061147a608089016111ea565b905092959891949750929550565b5f60208284031215611498575f80fd5b5051919050565b5f602082840312156114af575f80fd5b81356001600160601b0381168114610421575f80fd5b5f602082840312156114d5575f80fd5b81356001600160401b0381168114610421575f80fd5b5f602082840312156114fb575f80fd5b81356001600160581b0381168114610421575f80fd5b5f60208284031215611521575f80fd5b815160ff81168114610421575f80fd5b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215611569575f80fd5b8135610421816111d3565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561159b5761159b611574565b92915050565b5f600182016115b2576115b2611574565b5060010190565b60c081528660c0820152868860e08301375f60e08883018101919091526001600160a01b0396871660208301529486166040820152929094166060830152608082015260a0810192909252601f909201601f19160101919050565b600181815b8085111561164e57815f190482111561163457611634611574565b8085161561164157918102915b93841c9390800290611619565b509250929050565b5f826116645750600161159b565b8161167057505f61159b565b81600181146116865760028114611690576116ac565b600191505061159b565b60ff8411156116a1576116a1611574565b50506001821b61159b565b5060208310610133831016604e8410600b84101617156116cf575081810a61159b565b6116d98383611614565b805f19048211156116ec576116ec611574565b029392505050565b5f61042160ff84168361165656fea2646970667358221220ac2f73a8a42fb656e037faafe3f9cd5da4f8716016daabc5646a90ab4183ca4464736f6c63430008150033
Deployed Bytecode Sourcemap
1180:12699:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5707:700;;;;;;:::i;:::-;;:::i;:::-;;;1193:14:6;;1186:22;1168:41;;1156:2;1141:18;5707:700:3;;;;;;;;11782:1603;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;4903:174::-;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5034:23:3;;;;;:17;:23;;;;;:30;;;;;;;;;;;:36;;;;;;;;;;;;;5027:43;;;;;;;;-1:-1:-1;;;;;5027:43:3;;;;-1:-1:-1;;;5027:43:3;;-1:-1:-1;;;;;5027:43:3;;;;;;;;-1:-1:-1;;;5027:43:3;;-1:-1:-1;;;;;5027:43:3;;;;;-1:-1:-1;;;5027:43:3;;;;;;;;;;;;;;;4903:174;;;;;;;4301:13:6;;-1:-1:-1;;;;;4297:38:6;4279:57;;4396:4;4384:17;;;4378:24;-1:-1:-1;;;;;4374:55:6;4352:20;;;4345:85;4490:4;4478:17;;;4472:24;-1:-1:-1;;;;;4468:57:6;4446:20;;;4439:87;4596:4;4584:17;;;4578:24;4571:32;4564:40;4542:20;;;4535:70;;;;4266:3;4251:19;;4072:539;3461:94:3;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3461:94:3;;;-1:-1:-1;;;3461:94:3;;-1:-1:-1;;;;;3461:94:3;;-1:-1:-1;;;3461:94:3;;-1:-1:-1;;;;;3461:94:3;;-1:-1:-1;;;3461:94:3;;;;;;;;;;-1:-1:-1;;;;;4853:31:6;;;4835:50;;-1:-1:-1;;;;;4921:37:6;;;4916:2;4901:18;;4894:65;-1:-1:-1;;;;;4995:39:6;;;4975:18;;;4968:67;;;;5078:14;5071:22;5066:2;5051:18;;5044:50;4822:3;4807:19;3461:94:3;4616:484:6;7083:663:3;;;;;;:::i;:::-;;:::i;:::-;;8596:2375;;;;;;:::i;:::-;;:::i;5707:700::-;5927:21;;-1:-1:-1;;;5927:21:3;;-1:-1:-1;;;;;7143:32:6;;;5927:21:3;;;7125:51:6;5853:4:3;;5927:15;;;;;;7098:18:6;;5927:21:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5901:23;;;;;;;;:::i;:::-;-1:-1:-1;;;;;5901:47:3;;5897:65;;;-1:-1:-1;5957:5:3;5950:12;;5897:65;6024:20;;;;:11;:20;:::i;:::-;-1:-1:-1;;;;;6006:38:3;:15;:38;6002:56;;;-1:-1:-1;6053:5:3;6046:12;;6002:56;6141:23;;;;;;;;:::i;:::-;6102:36;;-1:-1:-1;;;6102:36:3;;-1:-1:-1;;;;;8192:15:6;;;6102:36:3;;;8174:34:6;6132:4:3;8224:18:6;;;8217:43;-1:-1:-1;;;;;6102:62:3;;;;;:15;;;;;8109:18:6;;6102:36:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:62;6098:80;;;-1:-1:-1;6173:5:3;6166:12;;6098:80;6236:23;;;;;;;;:::i;:::-;-1:-1:-1;;;;;6236:28:3;6263:1;6236:28;6232:46;;-1:-1:-1;6273:5:3;6266:12;;6232:46;6336:23;;;;;;;;:::i;:::-;-1:-1:-1;;;;;6336:28:3;6363:1;6336:28;6332:46;;-1:-1:-1;6373:5:3;6366:12;;6332:46;-1:-1:-1;6396:4:3;5707:700;;;;;;:::o;11782:1603::-;11913:31;11946:26;11974;12050:19;12072:5;-1:-1:-1;;;;;12072:14:3;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12050:38;-1:-1:-1;12158:5:3;-1:-1:-1;;;;;12138:33:3;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12138:33:3;;-1:-1:-1;;12138:33:3;;;;;;;;;;;;12127:44;;12187:9;12182:1197;12198:16;;;12182:1197;;;12235:28;12266:17;:27;12284:5;;12290:1;12284:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12266:27:3;;;;;;;;;;;;;;;;;-1:-1:-1;12266:27:3;;;:34;;;;;;;;;;:40;;;;;;;;;;;12235:71;;;;;;;;;-1:-1:-1;;;;;12235:71:3;;;;-1:-1:-1;;;12235:71:3;;-1:-1:-1;;;;;12235:71:3;;;;;;;;-1:-1:-1;;;12235:71:3;;-1:-1:-1;;;;;12235:71:3;;;;;;;;-1:-1:-1;;;12235:71:3;;;;;;;;;;;;-1:-1:-1;12340:5:3;;12346:1;12340:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;12321;12330:1;12321:11;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;12321:27:3;;;;;12385:16;;-1:-1:-1;;;;;12367:34:3;:15;:34;12363:102;;;12448:1;12421:8;12430:1;12421:11;;;;;;;;:::i;:::-;;;;;;;;;;;;:17;:29;;;;;;;;;;12363:102;12482:7;:19;;;-1:-1:-1;;;;;12482:24:3;12505:1;12482:24;12478:97;;12526:11;;12547:13;;12526:8;;12535:1;;12526:11;;;;;;:::i;:::-;;;;;;;;;;;;:17;:34;;;;;;;;;;12478:97;12620:7;:19;;;-1:-1:-1;;;;;12592:47:3;:5;-1:-1:-1;;;;;12592:15:3;;12608:5;;12614:1;12608:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;12592:25;;-1:-1:-1;;;;;;12592:25:3;;;;;;;-1:-1:-1;;;;;7143:32:6;;;12592:25:3;;;7125:51:6;7098:18;;12592:25:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;12588:120;;;12659:11;;12680:13;;12659:8;;12668:1;;12659:11;;;;;;:::i;:::-;;;;;;;;;;;;:17;:34;;;;;;;;;;12588:120;12768:7;:19;;;-1:-1:-1;;;;;12725:62:3;:5;-1:-1:-1;;;;;12725:15:3;;12741:5;;12747:1;12741:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;12725:40;;-1:-1:-1;;;;;;12725:40:3;;;;;;;-1:-1:-1;;;;;8192:15:6;;;12725:40:3;;;8174:34:6;12759:4:3;8224:18:6;;;8217:43;8109:18;;12725:40:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:62;12721:135;;;12807:11;;12828:13;;12807:8;;12816:1;;12807:11;;;;;;:::i;:::-;;;;;;;;;;;;:17;:34;;;;;;;;;;12721:135;12898:7;:19;;;-1:-1:-1;;;;;12870:47:3;:8;12879:1;12870:11;;;;;;;;:::i;:::-;;;;;;;:25;;:47;;;;;12998:18;13019:78;13041:7;:19;;;-1:-1:-1;;;;;13019:78:3;13062:7;:19;;;-1:-1:-1;;;;;13019:78:3;13083:13;13019:21;:78::i;:::-;12998:99;;13139:10;13111:8;13120:1;13111:11;;;;;;;;:::i;:::-;;;;;;;:25;;:38;;;;;13221:8;13230:1;13221:11;;;;;;;;:::i;:::-;;;;;;;:17;;;:22;;13242:1;13221:22;13217:152;;13263:32;13285:10;13263:32;;:::i;:::-;;;13335:7;:19;;;-1:-1:-1;;;;;13313:41:3;;;;;;:::i;:::-;;;13217:152;12221:1158;;12216:3;;;;:::i;:::-;;;12182:1197;;;;12002:1383;11782:1603;;;;;;;;:::o;7083:663::-;512:6:1;;522:1;512:11;504:34;;;;-1:-1:-1;;;504:34:1;;9971:2:6;504:34:1;;;9953:21:6;10010:2;9990:18;;;9983:30;-1:-1:-1;;;10029:18:6;;;10022:40;10079:18;;504:34:1;;;;;;;;;558:1;549:6;:10;;;7255::3::1;7237:29:::0;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;7237:36:3;;::::1;::::0;;;;;;;;:42;;::::1;::::0;;;;;;;;7309:20:::1;::::0;;::::1;:11:::0;:20:::1;:::i;:::-;7290:39:::0;;-1:-1:-1;;7290:39:3::1;-1:-1:-1::0;;;;;7290:39:3;;;::::1;;::::0;;7361:23:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;7339:45:::0;;-1:-1:-1;;;;;7339:45:3;;;::::1;-1:-1:-1::0;;;7339:45:3::1;-1:-1:-1::0;;7339:45:3;;::::1;;::::0;;7416:23:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;7394:45:::0;;-1:-1:-1;;;;;7394:45:3;;;::::1;-1:-1:-1::0;;;7394:45:3::1;-1:-1:-1::0;;;;7394:45:3;;::::1;;::::0;;7493:246:::1;7527:10;7559:5:::0;7587:4;7606:23:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;7643:20;;::::0;::::1;:11:::0;:20:::1;:::i;:::-;7677:23;::::0;;;::::1;::::0;::::1;;:::i;:::-;7493:246;::::0;;-1:-1:-1;;;;;10476:15:6;;;10458:34;;10528:15;;;10523:2;10508:18;;10501:43;10580:15;;;;10560:18;;;10553:43;;;;-1:-1:-1;;;;;10632:39:6;10627:2;10612:18;;10605:67;-1:-1:-1;;;;;10709:31:6;10703:3;10688:19;;10681:60;-1:-1:-1;;;;;10778:37:6;;;10438:3;10757:19;;10750:66;7714:15:3::1;10847:3:6::0;10832:19;;10825:35;10407:3;10392:19;7493:246:3::1;;;;;;;-1:-1:-1::0;;591:1:1;582:6;:10;-1:-1:-1;;7083:663:3:o;8596:2375::-;512:6:1;;522:1;512:11;504:34;;;;-1:-1:-1;;;504:34:1;;9971:2:6;504:34:1;;;9953:21:6;10010:2;9990:18;;;9983:30;-1:-1:-1;;;10029:18:6;;;10022:40;10079:18;;504:34:1;9769:334:6;504:34:1;558:1;549:6;:10;;;;8818:19:3::1;8840:5;-1:-1:-1::0;;;;;8840:14:3::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8818:38;;8867:21;8898::::0;8934:9:::1;8929:900;8945:16:::0;;::::1;8929:900;;;8982:29;9014:17;:27;9032:5;;9038:1;9032:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;9014:27:3::1;-1:-1:-1::0;;;;;9014:27:3::1;;;;;;;;;;;;:34;9042:5;-1:-1:-1::0;;;;;9014:34:3::1;-1:-1:-1::0;;;;;9014:34:3::1;;;;;;;;;;;;:40;9049:4;-1:-1:-1::0;;;;;9014:40:3::1;-1:-1:-1::0;;;;;9014:40:3::1;;;;;;;;;;;;8982:72;;9073:7;:15;;;;;;;;;;;;9069:63;;;9123:5;;9129:1;9123:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;9097:35;::::0;-1:-1:-1;;;;;;9097:35:3;;-1:-1:-1;;;;;7143:32:6;;;9097:35:3::1;::::0;::::1;7125:51:6::0;7098:18;;9097:35:3::1;6979:203:6::0;9069:63:3::1;9168:16:::0;;-1:-1:-1;;;;;9168:16:3::1;9150:15;:34;9146:93;;;9230:5;;9236:1;9230:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;9193:46;::::0;-1:-1:-1;;;9193:46:3;;-1:-1:-1;;;;;7143:32:6;;;9193:46:3::1;::::0;::::1;7125:51:6::0;7098:18;;9193:46:3::1;6979:203:6::0;9146:93:3::1;9257:19:::0;;-1:-1:-1;;;9257:19:3;::::1;-1:-1:-1::0;;;;;9257:19:3::1;;:24:::0;9253:75:::1;;9319:5;;9325:1;9319:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;9290:38;::::0;-1:-1:-1;;;9290:38:3;;-1:-1:-1;;;;;7143:32:6;;;9290:38:3::1;::::0;::::1;7125:51:6::0;7098:18;;9290:38:3::1;6979:203:6::0;9253:75:3::1;9453:19:::0;;9431:78:::1;::::0;-1:-1:-1;;;9453:19:3;::::1;-1:-1:-1::0;;;;;9453:19:3::1;::::0;-1:-1:-1;;;9474:19:3;::::1;-1:-1:-1::0;;;;;9474:19:3::1;9495:13:::0;9431:21:::1;:78::i;:::-;9414:95;::::0;;::::1;:::i;:::-;9636:19:::0;;9414:95;;-1:-1:-1;9619:36:3::1;::::0;-1:-1:-1;;;9636:19:3;::::1;-1:-1:-1::0;;;;;9636:19:3::1;9619:36:::0;::::1;:::i;:::-;9669:22:::0;;-1:-1:-1;;;;;9669:22:3::1;-1:-1:-1::0;;;9669:22:3::1;::::0;;9619:36;-1:-1:-1;9757:61:3::1;9780:5:::0;;9786:1;9780:8;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;9798:19:::0;;-1:-1:-1;;;;;9757:22:3;::::1;::::0;;9790:6;;-1:-1:-1;;;9798:19:3;::::1;-1:-1:-1::0;;;;;9798:19:3::1;9757:22;:61::i;:::-;-1:-1:-1::0;8963:3:3::1;::::0;::::1;:::i;:::-;;;8929:900;;;;9853:6;-1:-1:-1::0;;;;;9839:33:3::1;;9873:7;;9882:10;9894:5;9901:4;9907:13;9922;9839:97;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;9952:9;9947:1018;9963:16:::0;;::::1;9947:1018;;;10000:29;10032:17;:27;10050:5;;10056:1;10050:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;10032:27:3::1;-1:-1:-1::0;;;;;10032:27:3::1;;;;;;;;;;;;:34;10060:5;-1:-1:-1::0;;;;;10032:34:3::1;-1:-1:-1::0;;;;;10032:34:3::1;;;;;;;;;;;;:40;10067:4;-1:-1:-1::0;;;;;10032:40:3::1;-1:-1:-1::0;;;;;10032:40:3::1;;;;;;;;;;;;10000:72;;10091:7;:15;;;;;;;;;;;;10087:867;;;10353:19:::0;;10308:20:::1;::::0;10331:78:::1;::::0;-1:-1:-1;;;10353:19:3;::::1;-1:-1:-1::0;;;;;10353:19:3::1;::::0;-1:-1:-1;;;10374:19:3;::::1;-1:-1:-1::0;;;;;10374:19:3::1;10395:13:::0;10331:21:::1;:78::i;:::-;10308:101;;10428:53;10450:6;10458:5;;10464:1;10458:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;10428:21:3;::::1;::::0;:53;10468:12;10428:21:::1;:53::i;:::-;10505:253;10549:5;;10555:1;10549:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;10587:5;10623:4;10650:7;:19;;;;;;;;;;-1:-1:-1::0;;;;;10650:19:3::1;10691:12;10725:15;10505:253;;;;;;;;;;-1:-1:-1::0;;;;;12061:15:6;;;12043:34;;12113:15;;;12108:2;12093:18;;12086:43;12165:15;;;;12160:2;12145:18;;12138:43;-1:-1:-1;;;;;12217:39:6;12212:2;12197:18;;12190:67;12288:3;12273:19;;12266:35;;;;12023:3;12317:19;;12310:35;;;;11992:3;11977:19;;11719:632;10505:253:3::1;;;;;;;;-1:-1:-1::0;10825:23:3;;10866;;;;10087:867:::1;;;10945:5;;10951:1;10945:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;10917:37;::::0;-1:-1:-1;;;10917:37:3;;-1:-1:-1;;;;;7143:32:6;;;10917:37:3::1;::::0;::::1;7125:51:6::0;7098:18;;10917:37:3::1;6979:203:6::0;10087:867:3::1;-1:-1:-1::0;9981:3:3::1;::::0;::::1;:::i;:::-;;;9947:1018;;;-1:-1:-1::0;;591:1:1;582:6;:10;-1:-1:-1;;;;;;;;;8596:2375:3:o;13641:236::-;13788:7;13814:56;13837:11;13850:19;13856:13;13850:2;:19;:::i;:::-;13814:11;;:56;:22;:56::i;:::-;13807:63;13641:236;-1:-1:-1;;;;13641:236:3:o;1328:1616:2:-;1466:12;1636:4;1630:11;-1:-1:-1;;;1759:17:2;1752:93;1892:4;1888:1;1869:17;1865:25;1858:39;1976:2;1971;1952:17;1948:26;1941:38;2056:6;2051:2;2032:17;2028:26;2021:42;2860:2;2857:1;2852:3;2833:17;2830:1;2823:5;2816;2811:52;2379:16;2372:24;2366:2;2348:16;2345:24;2341:1;2337;2331:8;2328:15;2324:46;2321:76;2121:756;2110:767;;;2905:7;2897:40;;;;-1:-1:-1;;;2897:40:2;;13941:2:6;2897:40:2;;;13923:21:6;13980:2;13960:18;;;13953:30;-1:-1:-1;;;13999:18:6;;;13992:50;14059:18;;2897:40:2;13739:344:6;2897:40:2;1456:1488;1328:1616;;;;:::o;1331:505:5:-;1507:9;;;1638:19;;1631:27;1663:9;;1677;;;1674:16;;1660:31;1627:65;1617:121;;1722:1;1719;1712:12;1617:121;1801:19;;1331:505;-1:-1:-1;;1331:505:5:o;14:138:6:-;-1:-1:-1;;;;;96:31:6;;86:42;;76:70;;142:1;139;132:12;76:70;14:138;:::o;157:141::-;225:20;;254:38;225:20;254:38;:::i;:::-;157:141;;;:::o;303:162::-;369:5;414:3;405:6;400:3;396:16;392:26;389:46;;;431:1;428;421:12;389:46;-1:-1:-1;453:6:6;303:162;-1:-1:-1;303:162:6:o;470:553::-;592:6;600;608;661:3;649:9;640:7;636:23;632:33;629:53;;;678:1;675;668:12;629:53;717:9;704:23;736:38;768:5;736:38;:::i;:::-;793:5;-1:-1:-1;850:2:6;835:18;;822:32;863:40;822:32;863:40;:::i;:::-;922:7;-1:-1:-1;948:69:6;1009:7;1004:2;989:18;;948:69;:::i;:::-;938:79;;470:553;;;;;:::o;1220:367::-;1283:8;1293:6;1347:3;1340:4;1332:6;1328:17;1324:27;1314:55;;1365:1;1362;1355:12;1314:55;-1:-1:-1;1388:20:6;;-1:-1:-1;;;;;1420:30:6;;1417:50;;;1463:1;1460;1453:12;1417:50;1500:4;1492:6;1488:17;1476:29;;1560:3;1553:4;1543:6;1540:1;1536:14;1528:6;1524:27;1520:38;1517:47;1514:67;;;1577:1;1574;1567:12;1514:67;1220:367;;;;;:::o;1592:753::-;1722:6;1730;1738;1746;1799:2;1787:9;1778:7;1774:23;1770:32;1767:52;;;1815:1;1812;1805:12;1767:52;1854:9;1841:23;1873:38;1905:5;1873:38;:::i;:::-;1930:5;-1:-1:-1;1987:2:6;1972:18;;1959:32;2000:40;1959:32;2000:40;:::i;:::-;2059:7;-1:-1:-1;2117:2:6;2102:18;;2089:32;-1:-1:-1;;;;;2133:30:6;;2130:50;;;2176:1;2173;2166:12;2130:50;2215:70;2277:7;2268:6;2257:9;2253:22;2215:70;:::i;:::-;1592:753;;;;-1:-1:-1;2304:8:6;-1:-1:-1;;;;1592:753:6:o;2350:1136::-;2637:2;2689:21;;;2759:13;;2662:18;;;2781:22;;;2608:4;;2637:2;2822:3;;2841:18;;;;2878:4;2905:15;;;2608:4;2948:424;2962:6;2959:1;2956:13;2948:424;;;3021:13;;3063:9;;-1:-1:-1;;;;;3059:35:6;3047:48;;3139:11;;;3133:18;3153:4;3129:29;3115:12;;;3108:51;3182:4;3226:11;;;3220:18;3206:12;;;3199:40;3279:11;;3273:18;3259:12;;;3252:40;3312:12;;;;3347:15;;;;3091:1;2977:9;2948:424;;;-1:-1:-1;;3408:18:6;;3401:34;;;;3466:4;3451:20;;;3444:36;;;;-1:-1:-1;3389:3:6;;2350:1136;-1:-1:-1;;;;2350:1136:6:o;3491:576::-;3594:6;3602;3610;3663:2;3651:9;3642:7;3638:23;3634:32;3631:52;;;3679:1;3676;3669:12;3631:52;3718:9;3705:23;3737:38;3769:5;3737:38;:::i;:::-;3794:5;-1:-1:-1;3851:2:6;3836:18;;3823:32;3864:40;3823:32;3864:40;:::i;:::-;3923:7;-1:-1:-1;3982:2:6;3967:18;;3954:32;3995:40;3954:32;3995:40;:::i;:::-;4054:7;4044:17;;;3491:576;;;;;:::o;5676:1298::-;5835:6;5843;5851;5859;5867;5875;5883;5936:3;5924:9;5915:7;5911:23;5907:33;5904:53;;;5953:1;5950;5943:12;5904:53;5992:9;5979:23;6011:38;6043:5;6011:38;:::i;:::-;6068:5;-1:-1:-1;6125:2:6;6110:18;;6097:32;6138:40;6097:32;6138:40;:::i;:::-;6197:7;-1:-1:-1;6255:2:6;6240:18;;6227:32;-1:-1:-1;;;;;6308:14:6;;;6305:34;;;6335:1;6332;6325:12;6305:34;6374:70;6436:7;6427:6;6416:9;6412:22;6374:70;:::i;:::-;6463:8;;-1:-1:-1;6348:96:6;-1:-1:-1;6551:2:6;6536:18;;6523:32;;-1:-1:-1;6567:16:6;;;6564:36;;;6596:1;6593;6586:12;6564:36;6634:8;6623:9;6619:24;6609:34;;6681:7;6674:4;6670:2;6666:13;6662:27;6652:55;;6703:1;6700;6693:12;6652:55;6743:2;6730:16;6769:2;6761:6;6758:14;6755:34;;;6785:1;6782;6775:12;6755:34;6830:7;6825:2;6816:6;6812:2;6808:15;6804:24;6801:37;6798:57;;;6851:1;6848;6841:12;6798:57;6882:2;6878;6874:11;6864:21;;6904:6;6894:16;;;;;6929:39;6963:3;6952:9;6948:19;6929:39;:::i;:::-;6919:49;;5676:1298;;;;;;;;;;:::o;7187:184::-;7257:6;7310:2;7298:9;7289:7;7285:23;7281:32;7278:52;;;7326:1;7323;7316:12;7278:52;-1:-1:-1;7349:16:6;;7187:184;-1:-1:-1;7187:184:6:o;7376:292::-;7434:6;7487:2;7475:9;7466:7;7462:23;7458:32;7455:52;;;7503:1;7500;7493:12;7455:52;7542:9;7529:23;-1:-1:-1;;;;;7585:5:6;7581:38;7574:5;7571:49;7561:77;;7634:1;7631;7624:12;7673:284;7731:6;7784:2;7772:9;7763:7;7759:23;7755:32;7752:52;;;7800:1;7797;7790:12;7752:52;7839:9;7826:23;-1:-1:-1;;;;;7882:5:6;7878:30;7871:5;7868:41;7858:69;;7923:1;7920;7913:12;8271:290;8329:6;8382:2;8370:9;8361:7;8357:23;8353:32;8350:52;;;8398:1;8395;8388:12;8350:52;8437:9;8424:23;-1:-1:-1;;;;;8480:5:6;8476:36;8469:5;8466:47;8456:75;;8527:1;8524;8517:12;8566:273;8634:6;8687:2;8675:9;8666:7;8662:23;8658:32;8655:52;;;8703:1;8700;8693:12;8655:52;8735:9;8729:16;8785:4;8778:5;8774:16;8767:5;8764:27;8754:55;;8805:1;8802;8795:12;8844:127;8905:10;8900:3;8896:20;8893:1;8886:31;8936:4;8933:1;8926:15;8960:4;8957:1;8950:15;8976:127;9037:10;9032:3;9028:20;9025:1;9018:31;9068:4;9065:1;9058:15;9092:4;9089:1;9082:15;9108:254;9167:6;9220:2;9208:9;9199:7;9195:23;9191:32;9188:52;;;9236:1;9233;9226:12;9188:52;9275:9;9262:23;9294:38;9326:5;9294:38;:::i;9367:127::-;9428:10;9423:3;9419:20;9416:1;9409:31;9459:4;9456:1;9449:15;9483:4;9480:1;9473:15;9499:125;9564:9;;;9585:10;;;9582:36;;;9598:18;;:::i;:::-;9499:125;;;;:::o;9629:135::-;9668:3;9689:17;;;9686:43;;9709:18;;:::i;:::-;-1:-1:-1;9756:1:6;9745:13;;9629:135::o;10871:843::-;11194:3;11183:9;11176:22;11235:6;11229:3;11218:9;11214:19;11207:35;11293:6;11285;11279:3;11268:9;11264:19;11251:49;11350:1;11344:3;11320:22;;;11316:32;;11309:43;;;;-1:-1:-1;;;;;11500:15:6;;;11493:4;11478:20;;11471:45;11552:15;;;11547:2;11532:18;;11525:43;11604:15;;;;11599:2;11584:18;;11577:43;11651:3;11636:19;;11629:35;11451:3;11680:19;;11673:35;;;;11413:2;11392:15;;;-1:-1:-1;;11388:29:6;11373:45;11369:55;;;-1:-1:-1;10871:843:6:o;12356:422::-;12445:1;12488:5;12445:1;12502:270;12523:7;12513:8;12510:21;12502:270;;;12582:4;12578:1;12574:6;12570:17;12564:4;12561:27;12558:53;;;12591:18;;:::i;:::-;12641:7;12631:8;12627:22;12624:55;;;12661:16;;;;12624:55;12740:22;;;;12700:15;;;;12502:270;;;12506:3;12356:422;;;;;:::o;12783:806::-;12832:5;12862:8;12852:80;;-1:-1:-1;12903:1:6;12917:5;;12852:80;12951:4;12941:76;;-1:-1:-1;12988:1:6;13002:5;;12941:76;13033:4;13051:1;13046:59;;;;13119:1;13114:130;;;;13026:218;;13046:59;13076:1;13067:10;;13090:5;;;13114:130;13151:3;13141:8;13138:17;13135:43;;;13158:18;;:::i;:::-;-1:-1:-1;;13214:1:6;13200:16;;13229:5;;13026:218;;13328:2;13318:8;13315:16;13309:3;13303:4;13300:13;13296:36;13290:2;13280:8;13277:16;13272:2;13266:4;13263:12;13259:35;13256:77;13253:159;;;-1:-1:-1;13365:19:6;;;13397:5;;13253:159;13444:34;13469:8;13463:4;13444:34;:::i;:::-;13514:6;13510:1;13506:6;13502:19;13493:7;13490:32;13487:58;;;13525:18;;:::i;:::-;13563:20;;12783:806;-1:-1:-1;;;12783:806:6:o;13594:140::-;13652:5;13681:47;13722:4;13712:8;13708:19;13702:4;13681:47;:::i
Swarm Source
ipfs://ac2f73a8a42fb656e037faafe3f9cd5da4f8716016daabc5646a90ab4183ca44
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $1 | 2 | $2 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.