Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 9 from a total of 9 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Solve With Signa... | 18035210 | 508 days ago | IN | 0 ETH | 0.00804139 | ||||
Solve With Signa... | 18035132 | 508 days ago | IN | 0 ETH | 0.00831237 | ||||
Solve With Signa... | 18034901 | 508 days ago | IN | 0 ETH | 0.00690342 | ||||
Solve With Signa... | 18033519 | 508 days ago | IN | 0 ETH | 0.00393258 | ||||
Solve With Signa... | 18033383 | 508 days ago | IN | 0 ETH | 0.00628576 | ||||
Solve With Signa... | 18028194 | 509 days ago | IN | 0 ETH | 0.02061512 | ||||
Solve With Signa... | 18027954 | 509 days ago | IN | 0 ETH | 0.00132552 | ||||
Solve With Signa... | 18026619 | 509 days ago | IN | 0 ETH | 0.00642079 | ||||
Solve With Signa... | 18025935 | 509 days ago | IN | 0 ETH | 0.01140069 |
Loading...
Loading
Contract Name:
Memswap
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract Memswap is ReentrancyGuard { // --- Structs --- struct Intent { IERC20 tokenIn; IERC20 tokenOut; address maker; // The address allowed to solve or authorize others to solve address matchmaker; address source; uint16 feeBps; uint16 surplusBps; uint32 deadline; bool isPartiallyFillable; uint128 amountIn; uint128 endAmountOut; uint16 startAmountBps; uint16 expectedAmountBps; bytes signature; } struct IntentStatus { bool isValidated; bool isCancelled; uint128 amountFilled; } struct Authorization { uint128 maxAmountIn; uint128 minAmountOut; uint32 blockDeadline; bool isPartiallyFillable; } struct Solution { address to; bytes data; uint128 amount; } // --- Events --- event IntentCancelled(bytes32 indexed intentHash); event IntentPosted(); event IntentSolved( bytes32 indexed intentHash, address tokenIn, address tokenOut, address maker, address solver, uint128 amountIn, uint128 amountOut ); event IntentValidated(bytes32 indexed intentHash); // --- Errors --- error AuthorizationIsExpired(); error AuthorizationIsInsufficient(); error AuthorizationIsNotPartiallyFillable(); error IntentIsCancelled(); error IntentIsExpired(); error IntentIsFilled(); error IntentIsNotPartiallyFillable(); error InvalidSignature(); error InvalidSolution(); error MerkleTreeTooLarge(); error Unauthorized(); error UnsuccessfullCall(); // --- Fields --- bytes32 public immutable DOMAIN_SEPARATOR; bytes32 public immutable AUTHORIZATION_TYPEHASH; bytes32 public immutable INTENT_TYPEHASH; mapping(bytes32 => IntentStatus) public intentStatus; mapping(bytes32 => Authorization) public authorization; // --- Constructor --- constructor() { uint256 chainId; assembly { chainId := chainid() } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256( "EIP712Domain(" "string name," "string version," "uint256 chainId," "address verifyingContract" ")" ), keccak256("Memswap"), keccak256("1.0"), chainId, address(this) ) ); AUTHORIZATION_TYPEHASH = keccak256( abi.encodePacked( "Authorization(", "bytes32 intentHash,", "address authorizedSolver,", "uint128 maxAmountIn,", "uint128 minAmountOut,", "uint32 blockDeadline,", "bool isPartiallyFillable", ")" ) ); INTENT_TYPEHASH = keccak256( abi.encodePacked( "Intent(", "address tokenIn,", "address tokenOut,", "address maker,", "address matchmaker,", "address source,", "uint16 feeBps,", "uint16 surplusBps,", "uint32 deadline,", "bool isPartiallyFillable,", "uint128 amountIn,", "uint128 endAmountOut,", "uint16 startAmountBps,", "uint16 expectedAmountBps", ")" ) ); } // Fallback receive() external payable {} // Public methods /** * @notice Authorize an address to solve a particular intent * * @param intent Intent which is being solved * @param authorizedSolver The address authorized to solve the intent * @param auth Authorization details and conditions */ function authorize( Intent calldata intent, address authorizedSolver, Authorization calldata auth ) external { if (intent.matchmaker != msg.sender) { revert Unauthorized(); } bytes32 intentHash = getIntentHash(intent); bytes32 authId = keccak256( abi.encodePacked(intentHash, authorizedSolver) ); authorization[authId] = auth; } /** * @notice Make an intent available on-chain (this method doesn't do * anything useful, it's only used as a mechanism for intent * distribution) * * @custom:param intent Intent being made available */ function post( /** * @custom:name intent */ Intent calldata ) external { emit IntentPosted(); } /** * @notice Validate an arbitrary number of intents (the signature of each * intent will be checked thus resulting in skipping verification * on further attempts to solve the intent) * * @param intents Intents to validate */ function validate(Intent[] calldata intents) external { uint256 length = intents.length; for (uint256 i; i < length; ) { Intent calldata intent = intents[i]; bytes32 intentHash = getIntentHash(intent); _validateIntent(intentHash, intent.maker, intent.signature); emit IntentValidated(intentHash); unchecked { ++i; } } } /** * @notice Cancel an arbitrary number of intents * * @param intents Intents to cancel */ function cancel(Intent[] calldata intents) external nonReentrant { uint256 length = intents.length; for (uint256 i; i < length; ) { Intent calldata intent = intents[i]; if (intent.maker != msg.sender) { revert Unauthorized(); } bytes32 intentHash = getIntentHash(intent); IntentStatus memory status = intentStatus[intentHash]; status.isValidated = false; status.isCancelled = true; intentStatus[intentHash] = status; emit IntentCancelled(intentHash); unchecked { ++i; } } } /** * @notice Solve an intent * * @param intent Intent to solve * @param solution Solution for the intent */ function solve( Intent calldata intent, Solution calldata solution ) external nonReentrant { // The intent must be open or tied to the current solver if ( intent.matchmaker != address(0) && intent.matchmaker != msg.sender ) { revert Unauthorized(); } // Solve (no minimum amount out restrictions when filling without authorization) _solve(intent, solution, 0); } /** * @notice Solve an intent with authorization (compared to the regular `solve` * this method allows filling intents of a matchmaker as long as there * is a valid authorization in-place for the current solver). The auth * will be done on-chain (via a transaction from the matchmaker). * * @param intent Intent to solve * @param solution Solution for the intent */ function solveWithOnChainAuthorizationCheck( Intent calldata intent, Solution calldata solution ) external nonReentrant { bytes32 intentHash = getIntentHash(intent); // Fetch the authorization bytes32 authId = keccak256(abi.encodePacked(intentHash, msg.sender)); Authorization memory auth = authorization[authId]; // Check the authorization and solve _checkAuthorization(auth, solution.amount); _solve(intent, solution, auth.minAmountOut); } /** * @notice Solve an intent with authorization (compared to the regular `solve` * this method allows filling intents of a matchmaker as long as there * is a valid authorization in-place for the current solver). The auth * will be done off-chain (via a signature from the matchmaker). * * @param intent Intent to solve * @param solution Solution for the intent * @param auth Authorization details/conditions * @param signature Authorization signature */ function solveWithSignatureAuthorizationCheck( Intent calldata intent, Solution calldata solution, Authorization calldata auth, bytes calldata signature ) external nonReentrant { bytes32 intentHash = getIntentHash(intent); bytes32 authorizationHash = getAuthorizationHash( intentHash, msg.sender, auth ); // Verify the authorization bytes32 digest = _getEIP712Hash(authorizationHash); _assertValidSignature( intent.matchmaker, digest, digest, signature.length, signature ); // Check the authorization and solve _checkAuthorization(auth, solution.amount); _solve(intent, solution, auth.minAmountOut); } // View methods /** * @notice Get the EIP712 struct hash for an authorization * * @param intentHash Intent EIP712 struct hash to authorize * @param authorizedSolver Solver to authorize * @param auth Authorization details/conditions * * @return authorizationHash The EIP712 struct hash of the authorization */ function getAuthorizationHash( bytes32 intentHash, address authorizedSolver, Authorization memory auth ) public view returns (bytes32 authorizationHash) { authorizationHash = keccak256( abi.encode( AUTHORIZATION_TYPEHASH, intentHash, authorizedSolver, auth.maxAmountIn, auth.minAmountOut, auth.blockDeadline, auth.isPartiallyFillable ) ); } /** * @notice Get the EIP712 struct hash for an intent * * @param intent Intent to compute the hash for * * @return intentHash The EIP712 struct hash of the intent */ function getIntentHash( Intent memory intent ) public view returns (bytes32 intentHash) { intentHash = keccak256( abi.encode( INTENT_TYPEHASH, intent.tokenIn, intent.tokenOut, intent.maker, intent.matchmaker, intent.source, intent.feeBps, intent.surplusBps, intent.deadline, intent.isPartiallyFillable, intent.amountIn, intent.endAmountOut, intent.startAmountBps, intent.expectedAmountBps ) ); } // Internal methods /** * @dev Solve an intent * * @param intent Intent to solve * @param solution Solution for the intent * @param minAmountOut The minimum amount out the solution is required to fulfill */ function _solve( Intent calldata intent, Solution calldata solution, uint128 minAmountOut ) internal { bytes32 intentHash = getIntentHash(intent); // Verify deadline if (intent.deadline < block.timestamp) { revert IntentIsExpired(); } IntentStatus memory status = intentStatus[intentHash]; // Verify cancellation status if (status.isCancelled) { revert IntentIsCancelled(); } // Verify signature if (!status.isValidated) { _validateIntent(intentHash, intent.maker, intent.signature); } uint128 amountToFill; // Avoid "Stack too deep" errors by wrapping inside a block { // Ensure there's still some amount left to be filled uint128 amountAvailable = intent.amountIn - status.amountFilled; if (amountAvailable == 0) { revert IntentIsFilled(); } // Ensure non-partially-fillable intents are fully filled if ( !intent.isPartiallyFillable && solution.amount < amountAvailable ) { revert IntentIsNotPartiallyFillable(); } // Compute the amount available to fill amountToFill = solution.amount > amountAvailable ? amountAvailable : solution.amount; intentStatus[intentHash].amountFilled += amountToFill; } // Transfer inputs to fill contract if (amountToFill > 0) { _transferToken( intent.maker, solution.to, intent.tokenIn, amountToFill ); } // Execute solution // Avoid "Stack too deep" errors by wrapping inside a block { (bool result, ) = solution.to.call(solution.data); if (!result) { revert UnsuccessfullCall(); } } // Check uint128 endAmountOut = intent.endAmountOut; uint128 startAmountOut = endAmountOut + (endAmountOut * intent.startAmountBps) / 10000; uint128 expectedAmountOut = endAmountOut + (endAmountOut * intent.expectedAmountBps) / 10000; // (startAmount - endAmount) // requiredAmount = startAmount - ------------------------- // (deadline - now()) uint128 requiredAmountOut = startAmountOut - (startAmountOut - endAmountOut) / ( intent.deadline > uint32(block.timestamp) ? intent.deadline - uint32(block.timestamp) : 1 ); if (requiredAmountOut < minAmountOut) { revert InvalidSolution(); } uint256 tokenOutBalance = address(intent.tokenOut) == address(0) ? address(this).balance : intent.tokenOut.allowance(solution.to, address(this)); // Ensure the maker got at least what he intended if (tokenOutBalance < requiredAmountOut) { revert InvalidSolution(); } if (intent.source != address(0)) { uint256 amount; // Charge fee if (intent.feeBps > 0) { amount += (requiredAmountOut * intent.feeBps) / 10000; } // Charge surplus fee if ( intent.surplusBps > 0 && tokenOutBalance > expectedAmountOut && expectedAmountOut > requiredAmountOut ) { amount += ((tokenOutBalance - expectedAmountOut) * intent.surplusBps) / 10000; } // Transfer fees if (amount > 0) { _transferToken( solution.to, intent.source, intent.tokenOut, amount ); tokenOutBalance -= amount; } } // Transfer ouputs to maker if (tokenOutBalance > 0) { _transferToken( solution.to, intent.maker, intent.tokenOut, tokenOutBalance ); } emit IntentSolved( intentHash, address(intent.tokenIn), address(intent.tokenOut), intent.maker, msg.sender, amountToFill, uint128(tokenOutBalance) ); } /** * @dev Check an authorization * * @param auth Authorization to check * @param amount Amount to check the authorization against */ function _checkAuthorization( Authorization memory auth, uint128 amount ) internal view { // Ensure the authorization is not expired if (auth.blockDeadline < block.number) { revert AuthorizationIsExpired(); } // Ensure the amount doesn't exceed the maximum authorized amount if (auth.maxAmountIn < amount) { revert AuthorizationIsInsufficient(); } // Ensure non-partially-fillable authorizations are fully filled if (!auth.isPartiallyFillable && auth.maxAmountIn != amount) { revert AuthorizationIsNotPartiallyFillable(); } } /** * @dev Get the EIP712 hash of a struct hash * * @param structHash Struct hash to get the EIP712 hash for * * @return eip712Hash The resulting EIP712 hash */ function _getEIP712Hash( bytes32 structHash ) internal view returns (bytes32 eip712Hash) { eip712Hash = keccak256( abi.encodePacked(hex"1901", DOMAIN_SEPARATOR, structHash) ); } /** * @dev Validate an intent by checking its signature * * @param intentHash EIP712 intent struct hash to verify * @param maker The maker of the intent * @param signature The signature of the intent */ function _validateIntent( bytes32 intentHash, address maker, bytes calldata signature ) internal { _verifySignature(intentHash, maker, signature); // Mark the intent as validated intentStatus[intentHash].isValidated = true; } /** * @dev Helper method for transferring native and ERC20 tokens * * @param from Transfer from this address * @param to Transfer to this address * @param token Token to transfer * @param amount Amonut to transfer */ function _transferToken( address from, address to, IERC20 token, uint256 amount ) internal { bool success; // Represent native tokens as `address(0)` if (address(token) == address(0)) { (success, ) = to.call{value: amount}(""); } else { success = token.transferFrom(from, to, amount); } if (!success) { revert UnsuccessfullCall(); } } // Copied from Seaport's source code function _verifySignature( bytes32 intentHash, address signer, bytes memory signature ) internal view { // Skip signature verification if the signer is the caller if (signer == msg.sender) { return; } bytes32 originalDigest = _getEIP712Hash(intentHash); // Read the length of the signature from memory and place on the stack uint256 originalSignatureLength = signature.length; // Determine effective digest if signature has a valid bulk order size bytes32 digest; if (_isValidBulkOrderSize(originalSignatureLength)) { // Rederive order hash and digest using bulk order proof (intentHash) = _computeBulkOrderProof(signature, intentHash); digest = _getEIP712Hash(intentHash); } else { // Supply the original digest as the effective digest digest = originalDigest; } // Ensure that the signature for the digest is valid for the signer _assertValidSignature( signer, digest, originalDigest, originalSignatureLength, signature ); } function _isValidBulkOrderSize( uint256 signatureLength ) internal pure returns (bool validLength) { // Utilize assembly to validate the length: // (64 + x) + 3 + 32y where (0 <= x <= 1) and (1 <= y <= 24) assembly { validLength := and( lt(sub(signatureLength, 0x63), 0x2e2), lt(and(add(signatureLength, 0x1d), 0x1f), 0x2) ) } } function _computeBulkOrderProof( bytes memory proofAndSignature, bytes32 leaf ) internal pure returns (bytes32 bulkOrderHash) { // Declare arguments for the root hash and the height of the proof bytes32 root; uint256 height; // Utilize assembly to efficiently derive the root hash using the proof assembly { // Retrieve the length of the proof, key, and signature combined let fullLength := mload(proofAndSignature) // If proofAndSignature has odd length, it is a compact signature with 64 bytes let signatureLength := sub(65, and(fullLength, 1)) // Derive height (or depth of tree) with signature and proof length height := shr(0x5, sub(fullLength, signatureLength)) // Update the length in memory to only include the signature mstore(proofAndSignature, signatureLength) // Derive the pointer for the key using the signature length let keyPtr := add(proofAndSignature, add(0x20, signatureLength)) // Retrieve the three-byte key using the derived pointer let key := shr(0xe8, mload(keyPtr)) // Retrieve pointer to first proof element by applying a constant for the key size to the derived key pointer let proof := add(keyPtr, 0x3) // Compute level 1 let scratchPtr1 := shl(0x5, and(key, 1)) mstore(scratchPtr1, leaf) mstore(xor(scratchPtr1, 0x20), mload(proof)) // Compute remaining proofs for { let i := 1 } lt(i, height) { i := add(i, 1) } { proof := add(proof, 0x20) let scratchPtr := shl(0x5, and(shr(i, key), 1)) mstore(scratchPtr, keccak256(0, 0x40)) mstore(xor(scratchPtr, 0x20), mload(proof)) } // Compute root hash root := keccak256(0, 0x40) } // Retrieve appropriate typehash constant based on height. bytes32 rootTypeHash = _lookupBulkOrderTypehash(height); // Use the typehash and the root hash to derive final bulk order hash assembly { mstore(0, rootTypeHash) mstore(0x20, root) bulkOrderHash := keccak256(0, 0x40) } } function _lookupBulkOrderTypehash( uint256 treeHeight ) internal pure returns (bytes32 typeHash) { // kecca256("BatchIntent(Intent[2] tree)Intent(address tokenIn,address tokenOut,address maker,address matchmaker,address source,uint16 feeBps,uint16 surplusBps,uint32 deadline,bool isPartiallyFillable,uint128 amountIn,uint128 endAmountOut,uint16 startAmountBps,uint16 expectedAmountBps)") if (treeHeight == 1) { typeHash = 0xa09b55b2b0f1611c4db0b312fc7063c8438a51497adc137310360981267db3ef; } else if (treeHeight == 2) { typeHash = 0x04440a5b85b1ac9a5931adc223455ce5ee3db7c8a2779030b9b8db54e2b85799; } else if (treeHeight == 3) { typeHash = 0x3201a8c99184de74eeba60a0f95ba5677e2d05308248224cff5d53314a25b768; } else if (treeHeight == 4) { typeHash = 0x5f9c3a9757945e640a0e6f0fa11269b3d05f3516b8377caf06a22bcd47f19a0c; } else if (treeHeight == 5) { typeHash = 0x49b5887b13176700800be2e1ec7eece8e4683eba84310a7a49f8acda23a84cc9; } else if (treeHeight == 6) { typeHash = 0x5aba5e52e068d52122f8220dda000664baf304f522ceface6940df335ca128fb; } else if (treeHeight == 7) { typeHash = 0xa004a0ff682c47acac1378afc7985f7c43efbd1adea9248e30d6afad0b0211e8; } else if (treeHeight == 8) { typeHash = 0x0745413a2bfe7693ff806398f8d59424166d165d7c16591bcfa1d4ce7cc168f5; } else { revert MerkleTreeTooLarge(); } } function _assertValidSignature( address signer, bytes32 digest, bytes32 originalDigest, uint256 originalSignatureLength, bytes memory signature ) internal view { // Declare value for ecrecover equality or 1271 call success status bool success; // Utilize assembly to perform optimized signature verification check assembly { // Ensure that first word of scratch space is empty mstore(0, 0) // Get the length of the signature. let signatureLength := mload(signature) // Get the pointer to the value preceding the signature length // This will be used for temporary memory overrides - either the signature head for isValidSignature or the digest for ecrecover let wordBeforeSignaturePtr := sub(signature, 0x20) // Cache the current value behind the signature to restore it later let cachedWordBeforeSignature := mload(wordBeforeSignaturePtr) // Declare lenDiff + recoveredSigner scope to manage stack pressure { // Take the difference between the max ECDSA signature length and the actual signature length (overflow desired for any values > 65) // If the diff is not 0 or 1, it is not a valid ECDSA signature - move on to EIP1271 check let lenDiff := sub(65, signatureLength) // Declare variable for recovered signer let recoveredSigner // If diff is 0 or 1, it may be an ECDSA signature // Try to recover signer if iszero(gt(lenDiff, 1)) { // Read the signature `s` value let originalSignatureS := mload(add(signature, 0x40)) // Read the first byte of the word after `s` // If the signature is 65 bytes, this will be the real `v` value // If not, it will need to be modified - doing it this way saves an extra condition. let v := byte(0, mload(add(signature, 0x60))) // If lenDiff is 1, parse 64-byte signature as ECDSA if lenDiff { // Extract yParity from highest bit of vs and add 27 to get v v := add(shr(0xff, originalSignatureS), 27) // Extract canonical s from vs, all but the highest bit // Temporarily overwrite the original `s` value in the signature mstore( add(signature, 0x40), and( originalSignatureS, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ) ) } // Temporarily overwrite the signature length with `v` to conform to the expected input for ecrecover mstore(signature, v) // Temporarily overwrite the word before the length with `digest` to conform to the expected input for ecrecover mstore(wordBeforeSignaturePtr, digest) // Attempt to recover the signer for the given signature // Do not check the call status as ecrecover will return a null address if the signature is invalid pop( staticcall( gas(), 0x1, // Call ecrecover precompile wordBeforeSignaturePtr, // Use data memory location 0x80, // Size of digest, v, r, and s 0, // Write result to scratch space 0x20 // Provide size of returned result ) ) // Restore cached word before signature mstore(wordBeforeSignaturePtr, cachedWordBeforeSignature) // Restore cached signature length mstore(signature, signatureLength) // Restore cached signature `s` value mstore(add(signature, 0x40), originalSignatureS) // Read the recovered signer from the buffer given as return space for ecrecover recoveredSigner := mload(0) } // Set success to true if the signature provided was a valid // ECDSA signature and the signer is not the null address // Use gt instead of direct as success is used outside of assembly success := and(eq(signer, recoveredSigner), gt(signer, 0)) } // If the signature was not verified with ecrecover, try EIP1271 if iszero(success) { // Reset the original signature length mstore(signature, originalSignatureLength) // Temporarily overwrite the word before the signature length and use it as the // head of the signature input to `isValidSignature`, which has a value of 64 mstore(wordBeforeSignaturePtr, 0x40) // Get pointer to use for the selector of `isValidSignature` let selectorPtr := sub(signature, 0x44) // Cache the value currently stored at the selector pointer let cachedWordOverwrittenBySelector := mload(selectorPtr) // Cache the value currently stored at the digest pointer let cachedWordOverwrittenByDigest := mload(sub(signature, 0x40)) // Write the selector first, since it overlaps the digest mstore(selectorPtr, 0x44) // Next, write the original digest mstore(sub(signature, 0x40), originalDigest) // Call signer with `isValidSignature` to validate signature success := staticcall( gas(), signer, selectorPtr, add(originalSignatureLength, 0x64), 0, 0x20 ) // Determine if the signature is valid on successful calls if success { // If first word of scratch space does not contain EIP-1271 signature selector, revert if iszero( eq( mload(0), 0x1626ba7e00000000000000000000000000000000000000000000000000000000 ) ) { success := 0 } } // Restore the cached values overwritten by selector, digest and signature head mstore(wordBeforeSignaturePtr, cachedWordBeforeSignature) mstore(selectorPtr, cachedWordOverwrittenBySelector) mstore(sub(signature, 0x40), cachedWordOverwrittenByDigest) } } if (!success) { revert InvalidSignature(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @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); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AuthorizationIsExpired","type":"error"},{"inputs":[],"name":"AuthorizationIsInsufficient","type":"error"},{"inputs":[],"name":"AuthorizationIsNotPartiallyFillable","type":"error"},{"inputs":[],"name":"IntentIsCancelled","type":"error"},{"inputs":[],"name":"IntentIsExpired","type":"error"},{"inputs":[],"name":"IntentIsFilled","type":"error"},{"inputs":[],"name":"IntentIsNotPartiallyFillable","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidSolution","type":"error"},{"inputs":[],"name":"MerkleTreeTooLarge","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnsuccessfullCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"intentHash","type":"bytes32"}],"name":"IntentCancelled","type":"event"},{"anonymous":false,"inputs":[],"name":"IntentPosted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"intentHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"address","name":"maker","type":"address"},{"indexed":false,"internalType":"address","name":"solver","type":"address"},{"indexed":false,"internalType":"uint128","name":"amountIn","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"amountOut","type":"uint128"}],"name":"IntentSolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"intentHash","type":"bytes32"}],"name":"IntentValidated","type":"event"},{"inputs":[],"name":"AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INTENT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"authorization","outputs":[{"internalType":"uint128","name":"maxAmountIn","type":"uint128"},{"internalType":"uint128","name":"minAmountOut","type":"uint128"},{"internalType":"uint32","name":"blockDeadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"matchmaker","type":"address"},{"internalType":"address","name":"source","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"},{"internalType":"uint16","name":"surplusBps","type":"uint16"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"uint128","name":"endAmountOut","type":"uint128"},{"internalType":"uint16","name":"startAmountBps","type":"uint16"},{"internalType":"uint16","name":"expectedAmountBps","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Memswap.Intent","name":"intent","type":"tuple"},{"internalType":"address","name":"authorizedSolver","type":"address"},{"components":[{"internalType":"uint128","name":"maxAmountIn","type":"uint128"},{"internalType":"uint128","name":"minAmountOut","type":"uint128"},{"internalType":"uint32","name":"blockDeadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"}],"internalType":"struct Memswap.Authorization","name":"auth","type":"tuple"}],"name":"authorize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"matchmaker","type":"address"},{"internalType":"address","name":"source","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"},{"internalType":"uint16","name":"surplusBps","type":"uint16"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"uint128","name":"endAmountOut","type":"uint128"},{"internalType":"uint16","name":"startAmountBps","type":"uint16"},{"internalType":"uint16","name":"expectedAmountBps","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Memswap.Intent[]","name":"intents","type":"tuple[]"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"intentHash","type":"bytes32"},{"internalType":"address","name":"authorizedSolver","type":"address"},{"components":[{"internalType":"uint128","name":"maxAmountIn","type":"uint128"},{"internalType":"uint128","name":"minAmountOut","type":"uint128"},{"internalType":"uint32","name":"blockDeadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"}],"internalType":"struct Memswap.Authorization","name":"auth","type":"tuple"}],"name":"getAuthorizationHash","outputs":[{"internalType":"bytes32","name":"authorizationHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"matchmaker","type":"address"},{"internalType":"address","name":"source","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"},{"internalType":"uint16","name":"surplusBps","type":"uint16"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"uint128","name":"endAmountOut","type":"uint128"},{"internalType":"uint16","name":"startAmountBps","type":"uint16"},{"internalType":"uint16","name":"expectedAmountBps","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Memswap.Intent","name":"intent","type":"tuple"}],"name":"getIntentHash","outputs":[{"internalType":"bytes32","name":"intentHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"intentStatus","outputs":[{"internalType":"bool","name":"isValidated","type":"bool"},{"internalType":"bool","name":"isCancelled","type":"bool"},{"internalType":"uint128","name":"amountFilled","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"matchmaker","type":"address"},{"internalType":"address","name":"source","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"},{"internalType":"uint16","name":"surplusBps","type":"uint16"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"uint128","name":"endAmountOut","type":"uint128"},{"internalType":"uint16","name":"startAmountBps","type":"uint16"},{"internalType":"uint16","name":"expectedAmountBps","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Memswap.Intent","name":"","type":"tuple"}],"name":"post","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"matchmaker","type":"address"},{"internalType":"address","name":"source","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"},{"internalType":"uint16","name":"surplusBps","type":"uint16"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"uint128","name":"endAmountOut","type":"uint128"},{"internalType":"uint16","name":"startAmountBps","type":"uint16"},{"internalType":"uint16","name":"expectedAmountBps","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Memswap.Intent","name":"intent","type":"tuple"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct Memswap.Solution","name":"solution","type":"tuple"}],"name":"solve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"matchmaker","type":"address"},{"internalType":"address","name":"source","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"},{"internalType":"uint16","name":"surplusBps","type":"uint16"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"uint128","name":"endAmountOut","type":"uint128"},{"internalType":"uint16","name":"startAmountBps","type":"uint16"},{"internalType":"uint16","name":"expectedAmountBps","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Memswap.Intent","name":"intent","type":"tuple"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct Memswap.Solution","name":"solution","type":"tuple"}],"name":"solveWithOnChainAuthorizationCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"matchmaker","type":"address"},{"internalType":"address","name":"source","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"},{"internalType":"uint16","name":"surplusBps","type":"uint16"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"uint128","name":"endAmountOut","type":"uint128"},{"internalType":"uint16","name":"startAmountBps","type":"uint16"},{"internalType":"uint16","name":"expectedAmountBps","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Memswap.Intent","name":"intent","type":"tuple"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct Memswap.Solution","name":"solution","type":"tuple"},{"components":[{"internalType":"uint128","name":"maxAmountIn","type":"uint128"},{"internalType":"uint128","name":"minAmountOut","type":"uint128"},{"internalType":"uint32","name":"blockDeadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"}],"internalType":"struct Memswap.Authorization","name":"auth","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"solveWithSignatureAuthorizationCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"matchmaker","type":"address"},{"internalType":"address","name":"source","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"},{"internalType":"uint16","name":"surplusBps","type":"uint16"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"bool","name":"isPartiallyFillable","type":"bool"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"uint128","name":"endAmountOut","type":"uint128"},{"internalType":"uint16","name":"startAmountBps","type":"uint16"},{"internalType":"uint16","name":"expectedAmountBps","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct Memswap.Intent[]","name":"intents","type":"tuple[]"}],"name":"validate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e060405234801561001057600080fd5b506001600055604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527fa824f82ad76641f06bd470e908066402dd197198c1fad30f8a92d22b46bbcf5e918101919091527fe6bbd6277e1bf288eed5e8d1780f9a50b239e86b153736bceebccf4ea79d90b3606082015246608082018190523060a08301529060c00160408051808303601f190181529082905280516020918201206080526d082eae8d0dee4d2f4c2e8d2dedc560931b908201527f6279746573333220696e74656e74486173682c00000000000000000000000000602e8201527f6164647265737320617574686f72697a6564536f6c7665722c0000000000000060418201527f75696e74313238206d6178416d6f756e74496e2c000000000000000000000000605a8201527f75696e74313238206d696e416d6f756e744f75742c0000000000000000000000606e8201527f75696e74333220626c6f636b446561646c696e652c000000000000000000000060838201527f626f6f6c2069735061727469616c6c7946696c6c61626c6500000000000000006098820152602960f81b60b082015260b10160408051601f1981840301815290829052805160209182012060a052610386910166092dce8cadce8560cb1b81526f1859191c995cdcc81d1bdad95b925b8b60821b6007820152701859191c995cdcc81d1bdad95b93dd5d0b607a1b60178201526d1859191c995cdcc81b585ad95c8b60921b60288201527f61646472657373206d617463686d616b65722c0000000000000000000000000060368201526e1859191c995cdcc81cdbdd5c98d94b608a1b60498201526d1d5a5b9d0c4d88199959509c1ccb60921b6058820152711d5a5b9d0c4d881cdd5c9c1b1d5cd09c1ccb60721b60668201526f1d5a5b9d0ccc88191958591b1a5b994b60821b60788201527f626f6f6c2069735061727469616c6c7946696c6c61626c652c000000000000006088820152701d5a5b9d0c4c8e08185b5bdd5b9d125b8b607a1b60a18201527f75696e7431323820656e64416d6f756e744f75742c000000000000000000000060b28201527f75696e743136207374617274416d6f756e744270732c0000000000000000000060c78201527f75696e743136206578706563746564416d6f756e74427073000000000000000060dd820152602960f81b60f582015260f60190565b60408051601f19818403018152919052805160209091012060c0525060805160a05160c0516121de6103e6600039600081816103fc015261070a0152600081816101fb01526103880152600081816102c3015261137f01526121de6000f3fe6080604052600436106100e15760003560e01c80636b05d53b1161007f578063a42aeab011610059578063a42aeab0146103ca578063b082a274146103ea578063ccb8b9411461041e578063f27cab7b1461043e57600080fd5b80636b05d53b146103565780637339651214610376578063838d1ee1146103aa57600080fd5b8063219c7a15116100bb578063219c7a15146101c85780632adf642d146102915780633644e515146102b15780635c6741c0146102e557600080fd5b80630ff1b4e0146100ed578063181262f41461010f578063195508341461012f57600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010d610108366004611879565b61045e565b005b34801561011b57600080fd5b5061010d61012a3660046118dd565b610553565b34801561013b57600080fd5b5061018b61014a36600461191a565b600260205260009081526040902080546001909101546001600160801b0380831692600160801b9004169063ffffffff811690640100000000900460ff1684565b604080516001600160801b03958616815294909316602085015263ffffffff90911691830191909152151560608201526080015b60405180910390f35b3480156101d457600080fd5b506102836101e3366004611a75565b805160208083015160408085015160609586015182517f000000000000000000000000000000000000000000000000000000000000000081870152808401999099526001600160a01b0397909716958801959095526001600160801b039384166080880152921660a086015263ffffffff90921660c085015291151560e08085019190915282518085039091018152610100909301909152815191012090565b6040519081526020016101bf565b34801561029d57600080fd5b5061010d6102ac366004611ab4565b61057f565b3480156102bd57600080fd5b506102837f000000000000000000000000000000000000000000000000000000000000000081565b3480156102f157600080fd5b5061033061030036600461191a565b60016020526000908152604090205460ff808216916101008104909116906201000090046001600160801b031683565b60408051931515845291151560208401526001600160801b0316908201526060016101bf565b34801561036257600080fd5b5061010d610371366004611b3b565b610624565b34801561038257600080fd5b506102837f000000000000000000000000000000000000000000000000000000000000000081565b3480156103b657600080fd5b506102836103c5366004611dd2565b610706565b3480156103d657600080fd5b5061010d6103e5366004611879565b61082e565b3480156103f657600080fd5b506102837f000000000000000000000000000000000000000000000000000000000000000081565b34801561042a57600080fd5b5061010d610439366004611ab4565b6108aa565b34801561044a57600080fd5b5061010d610459366004611e07565b6109fa565b610466610aad565b60006104746103c584611e5f565b9050600081336040516020016104a692919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b60408051808303601f19018152828252805160209182012060008181526002835283902060808501845280546001600160801b038082168752600160801b909104169285019290925260019091015463ffffffff811684840152640100000000900460ff16151560608085019190915290935061053391839161052e91908801908801611e71565b610b0a565b61054285858360200151610ba9565b50505061054f6001600055565b5050565b6040517f6eb1fe1ed1c00dd61527fc7354d8d0c434c5c8b03017905e72bea0d2be20200c90600090a150565b8060005b8181101561061e573684848381811061059e5761059e611e95565b90506020028101906105b09190611eab565b905060006105c06103c583611e5f565b90506105e9816105d66060850160408601611ecc565b6105e46101a0860186611ee9565b61130d565b60405181907f3bd1ea4a475636648bca86ed7425633364005c4642017950f960629e3201dbaf90600090a25050600101610583565b50505050565b61062c610aad565b600061063a6103c587611e5f565b9050600061065282336101e336899003890189611f37565b9050600061065f8261136f565b90506106b661067460808a0160608b01611ecc565b82838888905089898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113b592505050565b6106d86106c836889003880188611f37565b61052e60608a0160408b01611e71565b6106f288886106ed60408a0160208b01611e71565b610ba9565b5050506106ff6001600055565b5050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000826000015183602001518460400151856060015186608001518760a001518860c001518960e001518a61010001518b61012001518c61014001518d61016001518e61018001516040516020016108119e9d9c9b9a999897969594939291909d8e526001600160a01b039c8d1660208f01529a8c1660408e0152988b1660608d0152968a1660808c01529490981660a08a015261ffff92831660c08a015290821660e089015263ffffffff166101008801529415156101208701526001600160801b03908116610140870152166101608501528216610180840152166101a08201526101c00190565b604051602081830303815290604052805190602001209050919050565b610836610aad565b60006108486080840160608501611ecc565b6001600160a01b03161415801561087757503361086b6080840160608501611ecc565b6001600160a01b031614155b15610894576040516282b42960e81b815260040160405180910390fd5b6108a082826000610ba9565b61054f6001600055565b6108b2610aad565b8060005b818110156109ee57368484838181106108d1576108d1611e95565b90506020028101906108e39190611eab565b9050336108f66060830160408401611ecc565b6001600160a01b03161461091c576040516282b42960e81b815260040160405180910390fd5b600061092a6103c583611e5f565b600081815260016020818152604080842081516060810183528154620100008082046001600160801b039081168487019081528985528488018981528b8b529890975283519751965161ffff1990931697151561ff00191697909717610100961515969096029590951771ffffffffffffffffffffffffffffffff0000191695169093029390931790925590519293509183917fc08eb64db16a39d2848960af04e3f16fb404d9d436a9f0e9d7d0d4854715c9dc91a28360010193505050506108b6565b505061054f6001600055565b33610a0b6080850160608601611ecc565b6001600160a01b031614610a31576040516282b42960e81b815260040160405180910390fd5b6000610a3f6103c585611e5f565b905060008184604051602001610a7192919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b60408051601f1981840301815291815281516020928301206000818152600290935291209091508390610aa48282611f53565b50505050505050565b600260005403610b035760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640160405180910390fd5b6002600055565b43826040015163ffffffff161015610b35576040516301a8648f60e51b815260040160405180910390fd5b81516001600160801b0380831691161015610b635760405163062e314b60e01b815260040160405180910390fd5b8160600151158015610b8b5750806001600160801b031682600001516001600160801b031614155b1561054f5760405163081a857d60e01b815260040160405180910390fd5b6000610bb76103c585611e5f565b905042610bcb610100860160e08701611fdb565b63ffffffff161015610bf0576040516340db9d8d60e11b815260040160405180910390fd5b6000818152600160209081526040918290208251606081018452905460ff80821615158352610100820416158015938301939093526201000090046001600160801b031692810192909252610c585760405163460f1ebb60e11b815260040160405180910390fd5b8051610c8057610c8082610c726060880160408901611ecc565b6105e46101a0890189611ee9565b60408101516000908190610c9c61014089016101208a01611e71565b610ca6919061200e565b9050806001600160801b0316600003610cd25760405163dbce013760e01b815260040160405180910390fd5b610ce461012088016101008901612035565b158015610d1157506001600160801b038116610d066060880160408901611e71565b6001600160801b0316105b15610d2f57604051634f2ffed760e01b815260040160405180910390fd5b6001600160801b038116610d496060880160408901611e71565b6001600160801b031611610d6c57610d676060870160408801611e71565b610d6e565b805b600085815260016020526040902080549193508391600290610da09084906201000090046001600160801b0316612052565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550506000816001600160801b03161115610e1357610e13610dea6060880160408901611ecc565b610df76020880188611ecc565b610e0460208a018a611ecc565b846001600160801b03166114aa565b6000610e226020870187611ecc565b6001600160a01b0316610e386020880188611ee9565b604051610e46929190612072565b6000604051808303816000865af19150503d8060008114610e83576040519150601f19603f3d011682016040523d82523d6000602084013e610e88565b606091505b5050905080610ea957604051629c48b560e51b815260040160405180910390fd5b506000610ebe61016088016101408901611e71565b90506000612710610ed76101808a016101608b01612082565b610ee59061ffff168461209d565b610eef91906120de565b610ef99083612052565b90506000612710610f126101a08b016101808c01612082565b610f209061ffff168561209d565b610f2a91906120de565b610f349084612052565b9050600063ffffffff4216610f506101008c0160e08d01611fdb565b63ffffffff1611610f62576001610f7e565b42610f746101008c0160e08d01611fdb565b610f7e9190612104565b63ffffffff16610f8e858561200e565b610f9891906120de565b610fa2908461200e565b9050876001600160801b0316816001600160801b03161015610fd75760405163d9c1988f60e01b815260040160405180910390fd5b600080610fea60408d0160208e01611ecc565b6001600160a01b0316146110965761100860408c0160208d01611ecc565b6001600160a01b031663dd62ed3e61102360208d018d611ecc565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190612121565b611098565b475b9050816001600160801b03168110156110c45760405163d9c1988f60e01b815260040160405180910390fd5b60006110d660a08d0160808e01611ecc565b6001600160a01b03161461122b576000806110f760c08e0160a08f01612082565b61ffff1611156111425761271061111460c08e0160a08f01612082565b6111229061ffff168561209d565b61112c91906120de565b61113f906001600160801b03168261213a565b90505b600061115460e08e0160c08f01612082565b61ffff1611801561116d5750836001600160801b031682115b801561118a5750826001600160801b0316846001600160801b0316115b156111da576127106111a260e08e0160c08f01612082565b61ffff166111b96001600160801b0387168561214d565b6111c39190612160565b6111cd9190612177565b6111d7908261213a565b90505b80156112295761121c6111f060208d018d611ecc565b8d60800160208101906112039190611ecc565b8e60200160208101906112169190611ecc565b846114aa565b611226818361214d565b91505b505b80156112645761126461124160208c018c611ecc565b61125160608e0160408f01611ecc565b8d60200160208101906112169190611ecc565b877fd6e19ae1c533d0e059acf6ce7b615562c06c54e924b5281d5b83fb2496bb638661129360208e018e611ecc565b8d60200160208101906112a69190611ecc565b8e60400160208101906112b99190611ecc565b604080516001600160a01b03948516815292841660208401529216818301523360608201526001600160801b038a81166080830152851660a082015290519081900360c00190a25050505050505050505050565b61134e848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115ae92505050565b5050506000908152600160208190526040909120805460ff19169091179055565b60405161190160f01b60208201527f0000000000000000000000000000000000000000000000000000000000000000602282015260428101829052600090606201610811565b60008060005281516020830380518260410360006001821161141e576040870151606088015160001a83156113fd57601b8260ff1c0190506001600160ff1b03821660408a01525b88528a85526020600060808760015afa508385528588526040880152506000515b8a148a1515169450849050611481578585526040825260448503925082516040860351604485528860408803526020600060648a01878e5afa9550851561147457630b135d3f60e11b6000511461147457600095505b828452908452603f198601525b505050806114a257604051638baa579f60e01b815260040160405180910390fd5b505050505050565b60006001600160a01b038316611513576040516001600160a01b038516908390600081818185875af1925050503d8060008114611503576040519150601f19603f3d011682016040523d82523d6000602084013e611508565b606091505b505080915050611591565b6040516323b872dd60e01b81526001600160a01b0386811660048301528581166024830152604482018490528416906323b872dd906064016020604051808303816000875af115801561156a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158e919061218b565b90505b806106ff57604051629c48b560e51b815260040160405180910390fd5b336001600160a01b038316036115c357505050565b60006115ce8461136f565b825190915060006102e26062198301106002601d8401601f1610161561160a576115f8848761161a565b95506116038661136f565b905061160d565b50815b6114a285828585886113b5565b600080600084516001811660410380820360051c9250808752806020018701915050805160e81c6003820191506001811660051b868152825160208218525060015b8381101561168957604060002082821c60051b60209081169182529384018051919094185260010161165c565b50505060406000209150600061169e826116b6565b60009081526020939093525050604090209392505050565b6000816001036116e757507fa09b55b2b0f1611c4db0b312fc7063c8438a51497adc137310360981267db3ef919050565b8160020361171657507f04440a5b85b1ac9a5931adc223455ce5ee3db7c8a2779030b9b8db54e2b85799919050565b8160030361174557507f3201a8c99184de74eeba60a0f95ba5677e2d05308248224cff5d53314a25b768919050565b8160040361177457507f5f9c3a9757945e640a0e6f0fa11269b3d05f3516b8377caf06a22bcd47f19a0c919050565b816005036117a357507f49b5887b13176700800be2e1ec7eece8e4683eba84310a7a49f8acda23a84cc9919050565b816006036117d257507f5aba5e52e068d52122f8220dda000664baf304f522ceface6940df335ca128fb919050565b8160070361180157507fa004a0ff682c47acac1378afc7985f7c43efbd1adea9248e30d6afad0b0211e8919050565b8160080361183057507f0745413a2bfe7693ff806398f8d59424166d165d7c16591bcfa1d4ce7cc168f5919050565b6040516343d8a7b560e01b815260040160405180910390fd5b919050565b60006101c0828403121561186157600080fd5b50919050565b60006060828403121561186157600080fd5b6000806040838503121561188c57600080fd5b823567ffffffffffffffff808211156118a457600080fd5b6118b08683870161184e565b935060208501359150808211156118c657600080fd5b506118d385828601611867565b9150509250929050565b6000602082840312156118ef57600080fd5b813567ffffffffffffffff81111561190657600080fd5b6119128482850161184e565b949350505050565b60006020828403121561192c57600080fd5b5035919050565b6001600160a01b038116811461194857600080fd5b50565b803561184981611933565b634e487b7160e01b600052604160045260246000fd5b6040516101c0810167ffffffffffffffff8111828210171561199057611990611956565b60405290565b6001600160801b038116811461194857600080fd5b803561184981611996565b63ffffffff8116811461194857600080fd5b8035611849816119b6565b801515811461194857600080fd5b8035611849816119d3565b6000608082840312156119fe57600080fd5b6040516080810181811067ffffffffffffffff82111715611a2157611a21611956565b6040529050808235611a3281611996565b81526020830135611a4281611996565b60208201526040830135611a55816119b6565b60408201526060830135611a68816119d3565b6060919091015292915050565b600080600060c08486031215611a8a57600080fd5b833592506020840135611a9c81611933565b9150611aab85604086016119ec565b90509250925092565b60008060208385031215611ac757600080fd5b823567ffffffffffffffff80821115611adf57600080fd5b818501915085601f830112611af357600080fd5b813581811115611b0257600080fd5b8660208260051b8501011115611b1757600080fd5b60209290920196919550909350505050565b60006080828403121561186157600080fd5b600080600080600060e08688031215611b5357600080fd5b853567ffffffffffffffff80821115611b6b57600080fd5b611b7789838a0161184e565b96506020880135915080821115611b8d57600080fd5b611b9989838a01611867565b9550611ba88960408a01611b29565b945060c0880135915080821115611bbe57600080fd5b818801915088601f830112611bd257600080fd5b813581811115611be157600080fd5b896020828501011115611bf357600080fd5b9699959850939650602001949392505050565b803561ffff8116811461184957600080fd5b600082601f830112611c2957600080fd5b813567ffffffffffffffff80821115611c4457611c44611956565b604051601f8301601f19908116603f01168101908282118183101715611c6c57611c6c611956565b81604052838152866020858801011115611c8557600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101c08284031215611cb857600080fd5b611cc061196c565b9050611ccb8261194b565b8152611cd96020830161194b565b6020820152611cea6040830161194b565b6040820152611cfb6060830161194b565b6060820152611d0c6080830161194b565b6080820152611d1d60a08301611c06565b60a0820152611d2e60c08301611c06565b60c0820152611d3f60e083016119c8565b60e0820152610100611d528184016119e1565b90820152610120611d648382016119ab565b90820152610140611d768382016119ab565b90820152610160611d88838201611c06565b90820152610180611d9a838201611c06565b908201526101a08281013567ffffffffffffffff811115611dba57600080fd5b611dc685828601611c18565b82840152505092915050565b600060208284031215611de457600080fd5b813567ffffffffffffffff811115611dfb57600080fd5b61191284828501611ca5565b600080600060c08486031215611e1c57600080fd5b833567ffffffffffffffff811115611e3357600080fd5b611e3f8682870161184e565b9350506020840135611e5081611933565b9150611aab8560408601611b29565b6000611e6b3683611ca5565b92915050565b600060208284031215611e8357600080fd5b8135611e8e81611996565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600082356101be19833603018112611ec257600080fd5b9190910192915050565b600060208284031215611ede57600080fd5b8135611e8e81611933565b6000808335601e19843603018112611f0057600080fd5b83018035915067ffffffffffffffff821115611f1b57600080fd5b602001915036819003821315611f3057600080fd5b9250929050565b600060808284031215611f4957600080fd5b611e8e83836119ec565b8135611f5e81611996565b6001600160801b03811690506001600160801b031981818454161783556020840135611f8981611996565b60801b16178155600181016040830135611fa2816119b6565b81546060850135611fb2816119d3565b64ff0000000081151560201b1663ffffffff841664ffffffffff19841617178455505050505050565b600060208284031215611fed57600080fd5b8135611e8e816119b6565b634e487b7160e01b600052601160045260246000fd5b6001600160801b0382811682821603908082111561202e5761202e611ff8565b5092915050565b60006020828403121561204757600080fd5b8135611e8e816119d3565b6001600160801b0381811683821601908082111561202e5761202e611ff8565b8183823760009101908152919050565b60006020828403121561209457600080fd5b611e8e82611c06565b6001600160801b038181168382160280821691908281146120c0576120c0611ff8565b505092915050565b634e487b7160e01b600052601260045260246000fd5b60006001600160801b03808416806120f8576120f86120c8565b92169190910492915050565b63ffffffff82811682821603908082111561202e5761202e611ff8565b60006020828403121561213357600080fd5b5051919050565b80820180821115611e6b57611e6b611ff8565b81810381811115611e6b57611e6b611ff8565b8082028115828204841417611e6b57611e6b611ff8565b600082612186576121866120c8565b500490565b60006020828403121561219d57600080fd5b8151611e8e816119d356fea26469706673582212204ebc1eee07a304322fc1497b5f35ff775094a24d4b710f338495e7054bf8164b64736f6c63430008130033
Deployed Bytecode
0x6080604052600436106100e15760003560e01c80636b05d53b1161007f578063a42aeab011610059578063a42aeab0146103ca578063b082a274146103ea578063ccb8b9411461041e578063f27cab7b1461043e57600080fd5b80636b05d53b146103565780637339651214610376578063838d1ee1146103aa57600080fd5b8063219c7a15116100bb578063219c7a15146101c85780632adf642d146102915780633644e515146102b15780635c6741c0146102e557600080fd5b80630ff1b4e0146100ed578063181262f41461010f578063195508341461012f57600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010d610108366004611879565b61045e565b005b34801561011b57600080fd5b5061010d61012a3660046118dd565b610553565b34801561013b57600080fd5b5061018b61014a36600461191a565b600260205260009081526040902080546001909101546001600160801b0380831692600160801b9004169063ffffffff811690640100000000900460ff1684565b604080516001600160801b03958616815294909316602085015263ffffffff90911691830191909152151560608201526080015b60405180910390f35b3480156101d457600080fd5b506102836101e3366004611a75565b805160208083015160408085015160609586015182517f2e7c6c83eca6a9f817af26781ec5999f18b71fda5627382cb9191900b438a6bd81870152808401999099526001600160a01b0397909716958801959095526001600160801b039384166080880152921660a086015263ffffffff90921660c085015291151560e08085019190915282518085039091018152610100909301909152815191012090565b6040519081526020016101bf565b34801561029d57600080fd5b5061010d6102ac366004611ab4565b61057f565b3480156102bd57600080fd5b506102837f5d956f06bcaa5e673dffff063451891bc4be7bb69d635776ec22af717b3e76c181565b3480156102f157600080fd5b5061033061030036600461191a565b60016020526000908152604090205460ff808216916101008104909116906201000090046001600160801b031683565b60408051931515845291151560208401526001600160801b0316908201526060016101bf565b34801561036257600080fd5b5061010d610371366004611b3b565b610624565b34801561038257600080fd5b506102837f2e7c6c83eca6a9f817af26781ec5999f18b71fda5627382cb9191900b438a6bd81565b3480156103b657600080fd5b506102836103c5366004611dd2565b610706565b3480156103d657600080fd5b5061010d6103e5366004611879565b61082e565b3480156103f657600080fd5b506102837f577dc98febdc18c4443a7dc4c3ed332ac5ee708f6b8a0a51d5139497d0ff57d481565b34801561042a57600080fd5b5061010d610439366004611ab4565b6108aa565b34801561044a57600080fd5b5061010d610459366004611e07565b6109fa565b610466610aad565b60006104746103c584611e5f565b9050600081336040516020016104a692919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b60408051808303601f19018152828252805160209182012060008181526002835283902060808501845280546001600160801b038082168752600160801b909104169285019290925260019091015463ffffffff811684840152640100000000900460ff16151560608085019190915290935061053391839161052e91908801908801611e71565b610b0a565b61054285858360200151610ba9565b50505061054f6001600055565b5050565b6040517f6eb1fe1ed1c00dd61527fc7354d8d0c434c5c8b03017905e72bea0d2be20200c90600090a150565b8060005b8181101561061e573684848381811061059e5761059e611e95565b90506020028101906105b09190611eab565b905060006105c06103c583611e5f565b90506105e9816105d66060850160408601611ecc565b6105e46101a0860186611ee9565b61130d565b60405181907f3bd1ea4a475636648bca86ed7425633364005c4642017950f960629e3201dbaf90600090a25050600101610583565b50505050565b61062c610aad565b600061063a6103c587611e5f565b9050600061065282336101e336899003890189611f37565b9050600061065f8261136f565b90506106b661067460808a0160608b01611ecc565b82838888905089898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113b592505050565b6106d86106c836889003880188611f37565b61052e60608a0160408b01611e71565b6106f288886106ed60408a0160208b01611e71565b610ba9565b5050506106ff6001600055565b5050505050565b60007f577dc98febdc18c4443a7dc4c3ed332ac5ee708f6b8a0a51d5139497d0ff57d4826000015183602001518460400151856060015186608001518760a001518860c001518960e001518a61010001518b61012001518c61014001518d61016001518e61018001516040516020016108119e9d9c9b9a999897969594939291909d8e526001600160a01b039c8d1660208f01529a8c1660408e0152988b1660608d0152968a1660808c01529490981660a08a015261ffff92831660c08a015290821660e089015263ffffffff166101008801529415156101208701526001600160801b03908116610140870152166101608501528216610180840152166101a08201526101c00190565b604051602081830303815290604052805190602001209050919050565b610836610aad565b60006108486080840160608501611ecc565b6001600160a01b03161415801561087757503361086b6080840160608501611ecc565b6001600160a01b031614155b15610894576040516282b42960e81b815260040160405180910390fd5b6108a082826000610ba9565b61054f6001600055565b6108b2610aad565b8060005b818110156109ee57368484838181106108d1576108d1611e95565b90506020028101906108e39190611eab565b9050336108f66060830160408401611ecc565b6001600160a01b03161461091c576040516282b42960e81b815260040160405180910390fd5b600061092a6103c583611e5f565b600081815260016020818152604080842081516060810183528154620100008082046001600160801b039081168487019081528985528488018981528b8b529890975283519751965161ffff1990931697151561ff00191697909717610100961515969096029590951771ffffffffffffffffffffffffffffffff0000191695169093029390931790925590519293509183917fc08eb64db16a39d2848960af04e3f16fb404d9d436a9f0e9d7d0d4854715c9dc91a28360010193505050506108b6565b505061054f6001600055565b33610a0b6080850160608601611ecc565b6001600160a01b031614610a31576040516282b42960e81b815260040160405180910390fd5b6000610a3f6103c585611e5f565b905060008184604051602001610a7192919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b60408051601f1981840301815291815281516020928301206000818152600290935291209091508390610aa48282611f53565b50505050505050565b600260005403610b035760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640160405180910390fd5b6002600055565b43826040015163ffffffff161015610b35576040516301a8648f60e51b815260040160405180910390fd5b81516001600160801b0380831691161015610b635760405163062e314b60e01b815260040160405180910390fd5b8160600151158015610b8b5750806001600160801b031682600001516001600160801b031614155b1561054f5760405163081a857d60e01b815260040160405180910390fd5b6000610bb76103c585611e5f565b905042610bcb610100860160e08701611fdb565b63ffffffff161015610bf0576040516340db9d8d60e11b815260040160405180910390fd5b6000818152600160209081526040918290208251606081018452905460ff80821615158352610100820416158015938301939093526201000090046001600160801b031692810192909252610c585760405163460f1ebb60e11b815260040160405180910390fd5b8051610c8057610c8082610c726060880160408901611ecc565b6105e46101a0890189611ee9565b60408101516000908190610c9c61014089016101208a01611e71565b610ca6919061200e565b9050806001600160801b0316600003610cd25760405163dbce013760e01b815260040160405180910390fd5b610ce461012088016101008901612035565b158015610d1157506001600160801b038116610d066060880160408901611e71565b6001600160801b0316105b15610d2f57604051634f2ffed760e01b815260040160405180910390fd5b6001600160801b038116610d496060880160408901611e71565b6001600160801b031611610d6c57610d676060870160408801611e71565b610d6e565b805b600085815260016020526040902080549193508391600290610da09084906201000090046001600160801b0316612052565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550506000816001600160801b03161115610e1357610e13610dea6060880160408901611ecc565b610df76020880188611ecc565b610e0460208a018a611ecc565b846001600160801b03166114aa565b6000610e226020870187611ecc565b6001600160a01b0316610e386020880188611ee9565b604051610e46929190612072565b6000604051808303816000865af19150503d8060008114610e83576040519150601f19603f3d011682016040523d82523d6000602084013e610e88565b606091505b5050905080610ea957604051629c48b560e51b815260040160405180910390fd5b506000610ebe61016088016101408901611e71565b90506000612710610ed76101808a016101608b01612082565b610ee59061ffff168461209d565b610eef91906120de565b610ef99083612052565b90506000612710610f126101a08b016101808c01612082565b610f209061ffff168561209d565b610f2a91906120de565b610f349084612052565b9050600063ffffffff4216610f506101008c0160e08d01611fdb565b63ffffffff1611610f62576001610f7e565b42610f746101008c0160e08d01611fdb565b610f7e9190612104565b63ffffffff16610f8e858561200e565b610f9891906120de565b610fa2908461200e565b9050876001600160801b0316816001600160801b03161015610fd75760405163d9c1988f60e01b815260040160405180910390fd5b600080610fea60408d0160208e01611ecc565b6001600160a01b0316146110965761100860408c0160208d01611ecc565b6001600160a01b031663dd62ed3e61102360208d018d611ecc565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190612121565b611098565b475b9050816001600160801b03168110156110c45760405163d9c1988f60e01b815260040160405180910390fd5b60006110d660a08d0160808e01611ecc565b6001600160a01b03161461122b576000806110f760c08e0160a08f01612082565b61ffff1611156111425761271061111460c08e0160a08f01612082565b6111229061ffff168561209d565b61112c91906120de565b61113f906001600160801b03168261213a565b90505b600061115460e08e0160c08f01612082565b61ffff1611801561116d5750836001600160801b031682115b801561118a5750826001600160801b0316846001600160801b0316115b156111da576127106111a260e08e0160c08f01612082565b61ffff166111b96001600160801b0387168561214d565b6111c39190612160565b6111cd9190612177565b6111d7908261213a565b90505b80156112295761121c6111f060208d018d611ecc565b8d60800160208101906112039190611ecc565b8e60200160208101906112169190611ecc565b846114aa565b611226818361214d565b91505b505b80156112645761126461124160208c018c611ecc565b61125160608e0160408f01611ecc565b8d60200160208101906112169190611ecc565b877fd6e19ae1c533d0e059acf6ce7b615562c06c54e924b5281d5b83fb2496bb638661129360208e018e611ecc565b8d60200160208101906112a69190611ecc565b8e60400160208101906112b99190611ecc565b604080516001600160a01b03948516815292841660208401529216818301523360608201526001600160801b038a81166080830152851660a082015290519081900360c00190a25050505050505050505050565b61134e848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115ae92505050565b5050506000908152600160208190526040909120805460ff19169091179055565b60405161190160f01b60208201527f5d956f06bcaa5e673dffff063451891bc4be7bb69d635776ec22af717b3e76c1602282015260428101829052600090606201610811565b60008060005281516020830380518260410360006001821161141e576040870151606088015160001a83156113fd57601b8260ff1c0190506001600160ff1b03821660408a01525b88528a85526020600060808760015afa508385528588526040880152506000515b8a148a1515169450849050611481578585526040825260448503925082516040860351604485528860408803526020600060648a01878e5afa9550851561147457630b135d3f60e11b6000511461147457600095505b828452908452603f198601525b505050806114a257604051638baa579f60e01b815260040160405180910390fd5b505050505050565b60006001600160a01b038316611513576040516001600160a01b038516908390600081818185875af1925050503d8060008114611503576040519150601f19603f3d011682016040523d82523d6000602084013e611508565b606091505b505080915050611591565b6040516323b872dd60e01b81526001600160a01b0386811660048301528581166024830152604482018490528416906323b872dd906064016020604051808303816000875af115801561156a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158e919061218b565b90505b806106ff57604051629c48b560e51b815260040160405180910390fd5b336001600160a01b038316036115c357505050565b60006115ce8461136f565b825190915060006102e26062198301106002601d8401601f1610161561160a576115f8848761161a565b95506116038661136f565b905061160d565b50815b6114a285828585886113b5565b600080600084516001811660410380820360051c9250808752806020018701915050805160e81c6003820191506001811660051b868152825160208218525060015b8381101561168957604060002082821c60051b60209081169182529384018051919094185260010161165c565b50505060406000209150600061169e826116b6565b60009081526020939093525050604090209392505050565b6000816001036116e757507fa09b55b2b0f1611c4db0b312fc7063c8438a51497adc137310360981267db3ef919050565b8160020361171657507f04440a5b85b1ac9a5931adc223455ce5ee3db7c8a2779030b9b8db54e2b85799919050565b8160030361174557507f3201a8c99184de74eeba60a0f95ba5677e2d05308248224cff5d53314a25b768919050565b8160040361177457507f5f9c3a9757945e640a0e6f0fa11269b3d05f3516b8377caf06a22bcd47f19a0c919050565b816005036117a357507f49b5887b13176700800be2e1ec7eece8e4683eba84310a7a49f8acda23a84cc9919050565b816006036117d257507f5aba5e52e068d52122f8220dda000664baf304f522ceface6940df335ca128fb919050565b8160070361180157507fa004a0ff682c47acac1378afc7985f7c43efbd1adea9248e30d6afad0b0211e8919050565b8160080361183057507f0745413a2bfe7693ff806398f8d59424166d165d7c16591bcfa1d4ce7cc168f5919050565b6040516343d8a7b560e01b815260040160405180910390fd5b919050565b60006101c0828403121561186157600080fd5b50919050565b60006060828403121561186157600080fd5b6000806040838503121561188c57600080fd5b823567ffffffffffffffff808211156118a457600080fd5b6118b08683870161184e565b935060208501359150808211156118c657600080fd5b506118d385828601611867565b9150509250929050565b6000602082840312156118ef57600080fd5b813567ffffffffffffffff81111561190657600080fd5b6119128482850161184e565b949350505050565b60006020828403121561192c57600080fd5b5035919050565b6001600160a01b038116811461194857600080fd5b50565b803561184981611933565b634e487b7160e01b600052604160045260246000fd5b6040516101c0810167ffffffffffffffff8111828210171561199057611990611956565b60405290565b6001600160801b038116811461194857600080fd5b803561184981611996565b63ffffffff8116811461194857600080fd5b8035611849816119b6565b801515811461194857600080fd5b8035611849816119d3565b6000608082840312156119fe57600080fd5b6040516080810181811067ffffffffffffffff82111715611a2157611a21611956565b6040529050808235611a3281611996565b81526020830135611a4281611996565b60208201526040830135611a55816119b6565b60408201526060830135611a68816119d3565b6060919091015292915050565b600080600060c08486031215611a8a57600080fd5b833592506020840135611a9c81611933565b9150611aab85604086016119ec565b90509250925092565b60008060208385031215611ac757600080fd5b823567ffffffffffffffff80821115611adf57600080fd5b818501915085601f830112611af357600080fd5b813581811115611b0257600080fd5b8660208260051b8501011115611b1757600080fd5b60209290920196919550909350505050565b60006080828403121561186157600080fd5b600080600080600060e08688031215611b5357600080fd5b853567ffffffffffffffff80821115611b6b57600080fd5b611b7789838a0161184e565b96506020880135915080821115611b8d57600080fd5b611b9989838a01611867565b9550611ba88960408a01611b29565b945060c0880135915080821115611bbe57600080fd5b818801915088601f830112611bd257600080fd5b813581811115611be157600080fd5b896020828501011115611bf357600080fd5b9699959850939650602001949392505050565b803561ffff8116811461184957600080fd5b600082601f830112611c2957600080fd5b813567ffffffffffffffff80821115611c4457611c44611956565b604051601f8301601f19908116603f01168101908282118183101715611c6c57611c6c611956565b81604052838152866020858801011115611c8557600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101c08284031215611cb857600080fd5b611cc061196c565b9050611ccb8261194b565b8152611cd96020830161194b565b6020820152611cea6040830161194b565b6040820152611cfb6060830161194b565b6060820152611d0c6080830161194b565b6080820152611d1d60a08301611c06565b60a0820152611d2e60c08301611c06565b60c0820152611d3f60e083016119c8565b60e0820152610100611d528184016119e1565b90820152610120611d648382016119ab565b90820152610140611d768382016119ab565b90820152610160611d88838201611c06565b90820152610180611d9a838201611c06565b908201526101a08281013567ffffffffffffffff811115611dba57600080fd5b611dc685828601611c18565b82840152505092915050565b600060208284031215611de457600080fd5b813567ffffffffffffffff811115611dfb57600080fd5b61191284828501611ca5565b600080600060c08486031215611e1c57600080fd5b833567ffffffffffffffff811115611e3357600080fd5b611e3f8682870161184e565b9350506020840135611e5081611933565b9150611aab8560408601611b29565b6000611e6b3683611ca5565b92915050565b600060208284031215611e8357600080fd5b8135611e8e81611996565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600082356101be19833603018112611ec257600080fd5b9190910192915050565b600060208284031215611ede57600080fd5b8135611e8e81611933565b6000808335601e19843603018112611f0057600080fd5b83018035915067ffffffffffffffff821115611f1b57600080fd5b602001915036819003821315611f3057600080fd5b9250929050565b600060808284031215611f4957600080fd5b611e8e83836119ec565b8135611f5e81611996565b6001600160801b03811690506001600160801b031981818454161783556020840135611f8981611996565b60801b16178155600181016040830135611fa2816119b6565b81546060850135611fb2816119d3565b64ff0000000081151560201b1663ffffffff841664ffffffffff19841617178455505050505050565b600060208284031215611fed57600080fd5b8135611e8e816119b6565b634e487b7160e01b600052601160045260246000fd5b6001600160801b0382811682821603908082111561202e5761202e611ff8565b5092915050565b60006020828403121561204757600080fd5b8135611e8e816119d3565b6001600160801b0381811683821601908082111561202e5761202e611ff8565b8183823760009101908152919050565b60006020828403121561209457600080fd5b611e8e82611c06565b6001600160801b038181168382160280821691908281146120c0576120c0611ff8565b505092915050565b634e487b7160e01b600052601260045260246000fd5b60006001600160801b03808416806120f8576120f86120c8565b92169190910492915050565b63ffffffff82811682821603908082111561202e5761202e611ff8565b60006020828403121561213357600080fd5b5051919050565b80820180821115611e6b57611e6b611ff8565b81810381811115611e6b57611e6b611ff8565b8082028115828204841417611e6b57611e6b611ff8565b600082612186576121866120c8565b500490565b60006020828403121561219d57600080fd5b8151611e8e816119d356fea26469706673582212204ebc1eee07a304322fc1497b5f35ff775094a24d4b710f338495e7054bf8164b64736f6c63430008130033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.