Contract Overview
Balance:
0 CELO
CELO Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x892c137432f3c48f67eac973f4624f7781febd0709c1385e42f03c1f1fd0f3c3 | 0x60806040 | 18242220 | 12 days 12 hrs ago | 0x81a662065d5c83fa9c5c12d0dc0104df57f85a12 | IN | Create: UnlockSwapPurchaser | 0 CELO | 0.02399795 |
[ Download CSV Export ]
Contract Name:
UnlockSwapPurchaser
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 80 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.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); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; library TransferHelper { /// @notice Transfers tokens from the targeted address to the given destination /// @notice Errors with 'STF' if transfer fails /// @param token The contract address of the token to be transferred /// @param from The originating address from which the tokens will be transferred /// @param to The destination address of the transfer /// @param value The amount to be transferred function safeTransferFrom( address token, address from, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); } /// @notice Transfers tokens from msg.sender to a recipient /// @dev Errors with ST if transfer fails /// @param token The contract address of the token which will be transferred /// @param to The recipient of the transfer /// @param value The value of the transfer function safeTransfer( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); } /// @notice Approves the stipulated contract to spend the given allowance in the given token /// @dev Errors with 'SA' if transfer fails /// @param token The contract address of the token to be approved /// @param to The target of the approval /// @param value The amount of the given token the target will be allowed to spend function safeApprove( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); } /// @notice Transfers ETH to the recipient address /// @dev Fails with `STE` /// @param to The destination of the transfer /// @param value The value to be transferred function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'STE'); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.17 <0.9.0; interface IMintableERC20 { function mint(address account, uint256 amount) external returns (bool); function transfer(address recipient, uint256 amount) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.17 <0.9.0; interface IPermit2 { function approve(address token, address spender, uint160 amount, uint48 expiration) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.17 <0.9.0; pragma experimental ABIEncoderV2; /** * @title The PublicLock Interface */ interface IPublicLock { /// Functions function initialize( address _lockCreator, uint _expirationDuration, address _tokenAddress, uint _keyPrice, uint _maxNumberOfKeys, string calldata _lockName ) external; // default role from OpenZeppelin function DEFAULT_ADMIN_ROLE() external view returns (bytes32 role); /** * @notice The version number of the current implementation on this network. * @return The current version number. */ function publicLockVersion() external pure returns (uint16); /** * @dev Called by lock manager to withdraw all funds from the lock * @param _tokenAddress specifies the token address to withdraw or 0 for ETH. This is usually * the same as `tokenAddress` in MixinFunds. * @param _recipient specifies the address that will receive the tokens * @param _amount specifies the max amount to withdraw, which may be reduced when * considering the available balance. Set to 0 or MAX_UINT to withdraw everything. * -- however be wary of draining funds as it breaks the `cancelAndRefund` and `expireAndRefundFor` use cases. */ function withdraw( address _tokenAddress, address payable _recipient, uint _amount ) external; /** * A function which lets a Lock manager of the lock to change the price for future purchases. * @dev Throws if called by other than a Lock manager * @dev Throws if lock has been disabled * @dev Throws if _tokenAddress is not a valid token * @param _keyPrice The new price to set for keys * @param _tokenAddress The address of the erc20 token to use for pricing the keys, * or 0 to use ETH */ function updateKeyPricing( uint _keyPrice, address _tokenAddress ) external; /** * Update the main key properties for the entire lock: * * - default duration of each key * - the maximum number of keys the lock can edit * - the maximum number of keys a single address can hold * * @notice keys previously bought are unaffected by this changes in expiration duration (i.e. * existing keys timestamps are not recalculated/updated) * @param _newExpirationDuration the new amount of time for each key purchased or type(uint).max for a non-expiring key * @param _maxKeysPerAcccount the maximum amount of key a single user can own * @param _maxNumberOfKeys uint the maximum number of keys * @dev _maxNumberOfKeys Can't be smaller than the existing supply */ function updateLockConfig( uint _newExpirationDuration, uint _maxNumberOfKeys, uint _maxKeysPerAcccount ) external; /** * Checks if the user has a non-expired key. * @param _user The address of the key owner */ function getHasValidKey( address _user ) external view returns (bool); /** * @dev Returns the key's ExpirationTimestamp field for a given owner. * @param _tokenId the id of the key * @dev Returns 0 if the owner has never owned a key for this lock */ function keyExpirationTimestampFor( uint _tokenId ) external view returns (uint timestamp); /** * Public function which returns the total number of unique owners (both expired * and valid). This may be larger than totalSupply. */ function numberOfOwners() external view returns (uint); /** * Allows the Lock owner to assign * @param _lockName a descriptive name for this Lock. * @param _lockSymbol a Symbol for this Lock (default to KEY). * @param _baseTokenURI the baseTokenURI for this Lock */ function setLockMetadata( string calldata _lockName, string calldata _lockSymbol, string calldata _baseTokenURI ) external; /** * @dev Gets the token symbol * @return string representing the token symbol */ function symbol() external view returns (string memory); /** @notice A distinct Uniform Resource Identifier (URI) for a given asset. * @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC * 3986. The URI may point to a JSON file that conforms to the "ERC721 * Metadata JSON Schema". * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md * @param _tokenId The tokenID we're inquiring about * @return String representing the URI for the requested token */ function tokenURI( uint256 _tokenId ) external view returns (string memory); /** * Allows a Lock manager to add or remove an event hook * @param _onKeyPurchaseHook Hook called when the `purchase` function is called * @param _onKeyCancelHook Hook called when the internal `_cancelAndRefund` function is called * @param _onValidKeyHook Hook called to determine if the contract should overide the status for a given address * @param _onTokenURIHook Hook called to generate a data URI used for NFT metadata * @param _onKeyTransferHook Hook called when a key is transfered * @param _onKeyExtendHook Hook called when a key is extended or renewed * @param _onKeyGrantHook Hook called when a key is granted */ function setEventHooks( address _onKeyPurchaseHook, address _onKeyCancelHook, address _onValidKeyHook, address _onTokenURIHook, address _onKeyTransferHook, address _onKeyExtendHook, address _onKeyGrantHook ) external; /** * Allows a Lock manager to give a collection of users a key with no charge. * Each key may be assigned a different expiration date. * @dev Throws if called by other than a Lock manager * @param _recipients An array of receiving addresses * @param _expirationTimestamps An array of expiration Timestamps for the keys being granted * @return the ids of the granted tokens */ function grantKeys( address[] calldata _recipients, uint[] calldata _expirationTimestamps, address[] calldata _keyManagers ) external returns (uint256[] memory); /** * Allows the Lock owner to extend an existing keys with no charge. * @param _tokenId The id of the token to extend * @param _duration The duration in secondes to add ot the key * @dev set `_duration` to 0 to use the default duration of the lock */ function grantKeyExtension( uint _tokenId, uint _duration ) external; /** * @dev Purchase function * @param _values array of tokens amount to pay for this purchase >= the current keyPrice - any applicable discount * (_values is ignored when using ETH) * @param _recipients array of addresses of the recipients of the purchased key * @param _referrers array of addresses of the users making the referral * @param _keyManagers optional array of addresses to grant managing rights to a specific address on creation * @param _data array of arbitrary data populated by the front-end which initiated the sale * @notice when called for an existing and non-expired key, the `_keyManager` param will be ignored * @dev Setting _value to keyPrice exactly doubles as a security feature. That way if the lock owner increases the * price while my transaction is pending I can't be charged more than I expected (only applicable to ERC-20 when more * than keyPrice is approved for spending). * @return tokenIds the ids of the created tokens */ function purchase( uint256[] calldata _values, address[] calldata _recipients, address[] calldata _referrers, address[] calldata _keyManagers, bytes[] calldata _data ) external payable returns (uint256[] memory tokenIds); /** * @dev Extend function * @param _value the number of tokens to pay for this purchase >= the current keyPrice - any applicable discount * (_value is ignored when using ETH) * @param _tokenId the id of the key to extend * @param _referrer address of the user making the referral * @param _data arbitrary data populated by the front-end which initiated the sale * @dev Throws if lock is disabled or key does not exist for _recipient. Throws if _recipient == address(0). */ function extend( uint _value, uint _tokenId, address _referrer, bytes calldata _data ) external payable; /** * Returns the percentage of the keyPrice to be sent to the referrer (in basis points) * @param _referrer the address of the referrer * @return referrerFee the percentage of the keyPrice to be sent to the referrer (in basis points) */ function referrerFees( address _referrer ) external view returns (uint referrerFee); /** * Set a specific percentage of the keyPrice to be sent to the referrer while purchasing, * extending or renewing a key. * @param _referrer the address of the referrer * @param _feeBasisPoint the percentage of the price to be used for this * specific referrer (in basis points) * @dev To send a fixed percentage of the key price to all referrers, sett a percentage to `address(0)` */ function setReferrerFee( address _referrer, uint _feeBasisPoint ) external; /** * Merge existing keys * @param _tokenIdFrom the id of the token to substract time from * @param _tokenIdTo the id of the destination token to add time * @param _amount the amount of time to transfer (in seconds) */ function mergeKeys( uint _tokenIdFrom, uint _tokenIdTo, uint _amount ) external; /** * Deactivate an existing key * @param _tokenId the id of token to burn * @notice the key will be expired and ownership records will be destroyed */ function burn(uint _tokenId) external; /** * @param _gasRefundValue price in wei or token in smallest price unit * @dev Set the value to be refunded to the sender on purchase */ function setGasRefundValue( uint256 _gasRefundValue ) external; /** * _gasRefundValue price in wei or token in smallest price unit * @dev Returns the value/rpice to be refunded to the sender on purchase */ function gasRefundValue() external view returns (uint256 _gasRefundValue); /** * @notice returns the minimum price paid for a purchase with these params. * @dev this considers any discount from Unlock or the OnKeyPurchase hook. */ function purchasePriceFor( address _recipient, address _referrer, bytes calldata _data ) external view returns (uint); /** * Allow a Lock manager to change the transfer fee. * @dev Throws if called by other than a Lock manager * @param _transferFeeBasisPoints The new transfer fee in basis-points(bps). * Ex: 200 bps = 2% */ function updateTransferFee( uint _transferFeeBasisPoints ) external; /** * Determines how much of a fee would need to be paid in order to * transfer to another account. This is pro-rated so the fee goes * down overtime. * @dev Throws if _tokenId does not have a valid key * @param _tokenId The id of the key check the transfer fee for. * @param _time The amount of time to calculate the fee for. * @return The transfer fee in seconds. */ function getTransferFee( uint _tokenId, uint _time ) external view returns (uint); /** * @dev Invoked by a Lock manager to expire the user's key * and perform a refund and cancellation of the key * @param _tokenId The key id we wish to refund to * @param _amount The amount to refund to the key-owner * @dev Throws if called by other than a Lock manager * @dev Throws if _keyOwner does not have a valid key */ function expireAndRefundFor( uint _tokenId, uint _amount ) external; /** * @dev allows the key manager to expire a given tokenId * and send a refund to the keyOwner based on the amount of time remaining. * @param _tokenId The id of the key to cancel. */ function cancelAndRefund(uint _tokenId) external; /** * Allow a Lock manager to change the refund penalty. * @dev Throws if called by other than a Lock manager * @param _freeTrialLength The new duration of free trials for this lock * @param _refundPenaltyBasisPoints The new refund penaly in basis-points(bps) */ function updateRefundPenalty( uint _freeTrialLength, uint _refundPenaltyBasisPoints ) external; /** * @dev Determines how much of a refund a key owner would receive if they issued * @param _tokenId the id of the token to get the refund value for. * @notice Due to the time required to mine a tx, the actual refund amount will be lower * than what the user reads from this call. * @return refund the amount of tokens refunded */ function getCancelAndRefundValue( uint _tokenId ) external view returns (uint refund); function addLockManager(address account) external; function isLockManager( address account ) external view returns (bool); /** * Returns the address of the `onKeyPurchaseHook` hook. * @return hookAddress address of the hook */ function onKeyPurchaseHook() external view returns (address hookAddress); /** * Returns the address of the `onKeyCancelHook` hook. * @return hookAddress address of the hook */ function onKeyCancelHook() external view returns (address hookAddress); /** * Returns the address of the `onValidKeyHook` hook. * @return hookAddress address of the hook */ function onValidKeyHook() external view returns (address hookAddress); /** * Returns the address of the `onTokenURIHook` hook. * @return hookAddress address of the hook */ function onTokenURIHook() external view returns (address hookAddress); /** * Returns the address of the `onKeyTransferHook` hook. * @return hookAddress address of the hook */ function onKeyTransferHook() external view returns (address hookAddress); /** * Returns the address of the `onKeyExtendHook` hook. * @return hookAddress the address ok the hook */ function onKeyExtendHook() external view returns (address hookAddress); /** * Returns the address of the `onKeyGrantHook` hook. * @return hookAddress the address ok the hook */ function onKeyGrantHook() external view returns (address hookAddress); function renounceLockManager() external; /** * @return the maximum number of key allowed for a single address */ function maxKeysPerAddress() external view returns (uint); function expirationDuration() external view returns (uint256); function freeTrialLength() external view returns (uint256); function keyPrice() external view returns (uint256); function maxNumberOfKeys() external view returns (uint256); function refundPenaltyBasisPoints() external view returns (uint256); function tokenAddress() external view returns (address); function transferFeeBasisPoints() external view returns (uint256); function unlockProtocol() external view returns (address); function keyManagerOf( uint ) external view returns (address); ///=================================================================== /** * @notice Allows the key owner to safely share their key (parent key) by * transferring a portion of the remaining time to a new key (child key). * @dev Throws if key is not valid. * @dev Throws if `_to` is the zero address * @param _to The recipient of the shared key * @param _tokenId the key to share * @param _timeShared The amount of time shared * checks if `_to` is a smart contract (code size > 0). If so, it calls * `onERC721Received` on `_to` and throws if the return value is not * `bytes4(keccak256('onERC721Received(address,address,uint,bytes)'))`. * @dev Emit Transfer event */ function shareKey( address _to, uint _tokenId, uint _timeShared ) external; /** * @notice Update transfer and cancel rights for a given key * @param _tokenId The id of the key to assign rights for * @param _keyManager The address to assign the rights to for the given key */ function setKeyManagerOf( uint _tokenId, address _keyManager ) external; /** * Check if a certain key is valid * @param _tokenId the id of the key to check validity * @notice this makes use of the onValidKeyHook if it is set */ function isValidKey( uint _tokenId ) external view returns (bool); /** * Returns the number of keys owned by `_keyOwner` (expired or not) * @param _keyOwner address for which we are retrieving the total number of keys * @return numberOfKeys total number of keys owned by the address */ function totalKeys( address _keyOwner ) external view returns (uint numberOfKeys); /// @notice A descriptive name for a collection of NFTs in this contract function name() external view returns (string memory _name); ///=================================================================== /// From ERC165.sol function supportsInterface( bytes4 interfaceId ) external view returns (bool); ///=================================================================== /// From ERC-721 /** * In the specific case of a Lock, `balanceOf` returns only the tokens with a valid expiration timerange * @return balance The number of valid keys owned by `_keyOwner` */ function balanceOf( address _owner ) external view returns (uint256 balance); /** * @dev Returns the owner of the NFT specified by `tokenId`. */ function ownerOf( uint256 tokenId ) external view returns (address _owner); /** * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to * another (`to`). * * Requirements: * - `from`, `to` cannot be zero. * - `tokenId` must be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this * NFT by either {approve} or {setApprovalForAll}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * an ERC721-like function to transfer a token from one account to another. * @param from the owner of token to transfer * @param to the address that will receive the token * @param tokenId the id of the token * @dev Requirements: if the caller is not `from`, it must be approved to move this token by * either {approve} or {setApprovalForAll}. * The key manager will be reset to address zero after the transfer */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * Lending a key allows you to transfer the token while retaining the * ownerships right by setting yourself as a key manager first. * @param from the owner of token to transfer * @param to the address that will receive the token * @param tokenId the id of the token * @notice This function can only be called by 1) the key owner when no key manager is set or 2) the key manager. * After calling the function, the `_recipent` will be the new owner, and the sender of the tx * will become the key manager. */ function lendKey( address from, address to, uint tokenId ) external; /** * Unlend is called when you have lent a key and want to claim its full ownership back. * @param _recipient the address that will receive the token ownership * @param _tokenId the id of the token * @dev Only the key manager of the token can call this function */ function unlendKey( address _recipient, uint _tokenId ) external; function approve(address to, uint256 tokenId) external; /** * @notice Get the approved address for a single NFT * @dev Throws if `_tokenId` is not a valid NFT. * @param _tokenId The NFT to find the approved address for * @return operator The approved address for this NFT, or the zero address if there is none */ function getApproved( uint256 _tokenId ) external view returns (address operator); /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf * @param _operator operator address to set the approval * @param _approved representing the status of the approval to be set * @notice disabled when transfers are disabled */ function setApprovalForAll( address _operator, bool _approved ) external; /** * @dev Tells whether an operator is approved by a given keyManager * @param _owner owner address which you want to query the approval of * @param _operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll( address _owner, address _operator ) external view returns (bool); function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; function totalSupply() external view returns (uint256); function tokenOfOwnerByIndex( address _owner, uint256 index ) external view returns (uint256 tokenId); function tokenByIndex( uint256 index ) external view returns (uint256); /** * Innherited from Open Zeppelin AccessControl.sol */ function getRoleAdmin( bytes32 role ) external view returns (bytes32); function grantRole( bytes32 role, address account ) external; function revokeRole( bytes32 role, address account ) external; function renounceRole( bytes32 role, address account ) external; function hasRole( bytes32 role, address account ) external view returns (bool); /** * @param _tokenId the id of the token to transfer time from * @param _to the recipient of the new token with time * @param _value sends a token with _value * expirationDuration (the amount of time remaining on a standard purchase). * @dev The typical use case would be to call this with _value 1, which is on par with calling `transferFrom`. If the user * has more than `expirationDuration` time remaining this may use the `shareKey` function to send some but not all of the token. * @return success the result of the transfer operation */ function transfer( uint _tokenId, address _to, uint _value ) external returns (bool success); /** `owner()` is provided as an helper to mimick the `Ownable` contract ABI. * The `Ownable` logic is used by many 3rd party services to determine * contract ownership - e.g. who is allowed to edit metadata on Opensea. * * @notice This logic is NOT used internally by the Unlock Protocol and is made * available only as a convenience helper. */ function owner() external view returns (address owner); function setOwner(address account) external; function isOwner( address account ) external view returns (bool isOwner); /** * Migrate data from the previous single owner => key mapping to * the new data structure w multiple tokens. * @param _calldata an ABI-encoded representation of the params (v10: the number of records to migrate as `uint`) * @dev when all record schemas are sucessfully upgraded, this function will update the `schemaVersion` * variable to the latest/current lock version */ function migrate(bytes calldata _calldata) external; /** * Returns the version number of the data schema currently used by the lock * @notice if this is different from `publicLockVersion`, then the ability to purchase, grant * or extend keys is disabled. * @dev will return 0 if no ;igration has ever been run */ function schemaVersion() external view returns (uint); /** * Set the schema version to the latest * @notice only lock manager call call this */ function updateSchemaVersion() external; /** * Renew a given token * @notice only works for non-free, expiring, ERC20 locks * @param _tokenId the ID fo the token to renew * @param _referrer the address of the person to be granted UDT */ function renewMembershipFor( uint _tokenId, address _referrer ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.17 <0.9.0; /** * @title The Unlock Interface **/ interface IUnlock { // Use initialize instead of a constructor to support proxies(for upgradeability via zos). function initialize(address _unlockOwner) external; /** * @dev deploy a ProxyAdmin contract used to upgrade locks */ function initializeProxyAdmin() external; /** * Retrieve the contract address of the proxy admin that manages the locks * @return the address of the ProxyAdmin instance */ function proxyAdminAddress() external view returns (address); /** * @notice Create lock (legacy) * This deploys a lock for a creator. It also keeps track of the deployed lock. * @param _expirationDuration the duration of the lock (pass 0 for unlimited duration) * @param _tokenAddress set to the ERC20 token address, or 0 for ETH. * @param _keyPrice the price of each key * @param _maxNumberOfKeys the maximum nimbers of keys to be edited * @param _lockName the name of the lock * param _salt [deprec] -- kept only for backwards copatibility * This may be implemented as a sequence ID or with RNG. It's used with `create2` * to know the lock's address before the transaction is mined. * @dev internally call `createUpgradeableLock` */ function createLock( uint _expirationDuration, address _tokenAddress, uint _keyPrice, uint _maxNumberOfKeys, string calldata _lockName, bytes12 // _salt ) external returns (address); /** * @notice Create lock (default) * This deploys a lock for a creator. It also keeps track of the deployed lock. * @param data bytes containing the call to initialize the lock template * @dev this call is passed as encoded function - for instance: * bytes memory data = abi.encodeWithSignature( * 'initialize(address,uint256,address,uint256,uint256,string)', * msg.sender, * _expirationDuration, * _tokenAddress, * _keyPrice, * _maxNumberOfKeys, * _lockName * ); * @return address of the create lock */ function createUpgradeableLock( bytes memory data ) external returns (address); /** * Create an upgradeable lock using a specific PublicLock version * @param data bytes containing the call to initialize the lock template * (refer to createUpgradeableLock for more details) * @param _lockVersion the version of the lock to use */ function createUpgradeableLockAtVersion( bytes memory data, uint16 _lockVersion ) external returns (address); /** * @notice Upgrade a lock to a specific version * @dev only available for publicLockVersion > 10 (proxyAdmin /required) * @param lockAddress the existing lock address * @param version the version number you are targeting * Likely implemented with OpenZeppelin TransparentProxy contract */ function upgradeLock( address payable lockAddress, uint16 version ) external returns (address); /** * This function keeps track of the added GDP, as well as grants of discount tokens * to the referrer, if applicable. * The number of discount tokens granted is based on the value of the referal, * the current growth rate and the lock's discount token distribution rate * This function is invoked by a previously deployed lock only. */ function recordKeyPurchase( uint _value, address _referrer // solhint-disable-line no-unused-vars ) external; /** * @notice [DEPRECATED] Call to this function has been removed from PublicLock > v9. * @dev [DEPRECATED] Kept for backwards compatibility * This function will keep track of consumed discounts by a given user. * It will also grant discount tokens to the creator who is granting the discount based on the * amount of discount and compensation rate. * This function is invoked by a previously deployed lock only. */ function recordConsumedDiscount( uint _discount, uint _tokens // solhint-disable-line no-unused-vars ) external view; /** * @notice [DEPRECATED] Call to this function has been removed from PublicLock > v9. * @dev [DEPRECATED] Kept for backwards compatibility * This function returns the discount available for a user, when purchasing a * a key from a lock. * This does not modify the state. It returns both the discount and the number of tokens * consumed to grant that discount. */ function computeAvailableDiscountFor( address _purchaser, // solhint-disable-line no-unused-vars uint _keyPrice // solhint-disable-line no-unused-vars ) external pure returns (uint discount, uint tokens); // Function to read the globalTokenURI field. function globalBaseTokenURI() external view returns (string memory); /** * @dev Redundant with globalBaseTokenURI() for backwards compatibility with v3 & v4 locks. */ function getGlobalBaseTokenURI() external view returns (string memory); // Function to read the globalTokenSymbol field. function globalTokenSymbol() external view returns (string memory); // Function to read the chainId field. function chainId() external view returns (uint); /** * @dev Redundant with globalTokenSymbol() for backwards compatibility with v3 & v4 locks. */ function getGlobalTokenSymbol() external view returns (string memory); /** * @notice Allows the owner to update configuration variables */ function configUnlock( address _udt, address _weth, uint _estimatedGasForPurchase, string calldata _symbol, string calldata _URI, uint _chainId ) external; /** * @notice Add a PublicLock template to be used for future calls to `createLock`. * @dev This is used to upgrade conytract per version number */ function addLockTemplate( address impl, uint16 version ) external; /** * Match lock templates addresses with version numbers * @param _version the number of the version of the template * @return address of the lock templates */ function publicLockImpls( uint16 _version ) external view returns (address); /** * Match version numbers with lock templates addresses * @param _impl the address of the deployed template contract (PublicLock) * @return number of the version corresponding to this address */ function publicLockVersions( address _impl ) external view returns (uint16); /** * Retrive the latest existing lock template version * @return the version number of the latest template (used to deploy contracts) */ function publicLockLatestVersion() external view returns (uint16); /** * @notice Upgrade the PublicLock template used for future calls to `createLock`. * @dev This will initialize the template and revokeOwnership. */ function setLockTemplate( address payable _publicLockAddress ) external; // Allows the owner to change the value tracking variables as needed. function resetTrackedValue( uint _grossNetworkProduct, uint _totalDiscountGranted ) external; function grossNetworkProduct() external view returns (uint); function totalDiscountGranted() external view returns (uint); function locks( address ) external view returns ( bool deployed, uint totalSales, uint yieldedDiscountTokens ); // The address of the public lock template, used when `createLock` is called function publicLockAddress() external view returns (address); // Map token address to exchange contract address if the token is supported // Used for GDP calculations function uniswapOracles( address ) external view returns (address); // The WETH token address, used for value calculations function weth() external view returns (address); // The UDT token address, used to mint tokens on referral function udt() external view returns (address); // The approx amount of gas required to purchase a key function estimatedGasForPurchase() external view returns (uint); /** * Helper to get the network mining basefee as introduced in EIP-1559 * @dev this helper can be wrapped in try/catch statement to avoid * revert in networks where EIP-1559 is not implemented */ function networkBaseFee() external view returns (uint); // The version number of the current Unlock implementation on this network function unlockVersion() external pure returns (uint16); /** * @notice allows the owner to set the oracle address to use for value conversions * setting the _oracleAddress to address(0) removes support for the token * @dev This will also call update to ensure at least one datapoint has been recorded. */ function setOracle( address _tokenAddress, address _oracleAddress ) external; // Initialize the Ownable contract, granting contract ownership to the specified sender function __initializeOwnable(address sender) external; /** * @dev Returns true if the caller is the current owner. */ function isOwner() external view returns (bool); /** * @dev Returns the address of the current owner. */ function owner() external view returns (address); /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() external; /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) external; /** * Set the fee collected by the protocol * @param _protocolFee fee (in basis points) */ function setProtocolFee(uint _protocolFee) external; /** * The fee (in basis points) collected by the protocol on each purchase / extension / renewal of a key * @return the protocol fee in basic point */ function protocolFee() external view returns (uint); /** * Call executed by a lock after its version upgrade triggred by `upgradeLock` * - PublicLock v12 > v13 (mainnet): migrate an existing Lock to another instance * of the Unlock contract * @dev The `msg.sender` will be the upgraded lock */ function postLockUpgrade() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol'; import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol'; import "../interfaces/IMintableERC20.sol"; import "../interfaces/IPermit2.sol"; import "../interfaces/IPublicLock.sol"; import "../interfaces/IUnlock.sol"; contract UnlockSwapPurchaser { // Unlock address on current chain address public unlockAddress; // required by Uniswap Universal Router address public permit2; mapping (address => bool) uniswapRouters; // events event SwapCall( address lock, address tokenAddress, uint amountSpent ); // errors error SwapFailed(address uniswapRouter, address tokenIn, address tokenOut, uint amountInMax, bytes callData); error LockDoesntExist(address lockAddress); error InsufficientBalance(); error UnauthorizedBalanceChange(); error LockCallFailed(); error WithdrawFailed(); error UnautorizedRouter(address routerAddress); /** * Set the address of Uniswap Permit2 helper contract * @param _unlockAddress the address of Unlock contract * @param _permit2Address the address of Uniswap PERMIT2 contract */ constructor(address _unlockAddress, address _permit2Address, address[] memory _uniswapRouters) { unlockAddress = _unlockAddress; permit2 = _permit2Address; for (uint i = 0; i < _uniswapRouters.length; i++) { uniswapRouters[_uniswapRouters[i]] = true; } } /** * Simple helper to retrieve balance in ERC20 or native tokens * @param token the address of the token (address(0) for native token) */ function getBalance(address token) internal view returns (uint) { return token == address(0) ? address(this).balance : IMintableERC20(token).balanceOf(address(this)); } /** * Swap tokens and call a function a lock contract. * * Calling this function will 1) swap the token sent by the user into the token (ERCC20 or native) used by * the lock contract using Uniswap Universal Router and 2) call the lock contract with the specified calldata * * @param lock the address of the lock * @param srcToken the address of the token sent by the user (ERC20 or address(0) for native) * @param amountInMax the maximum amount the user want to spend in the swap * @param uniswapRouter the address of the uniswap router * @param swapCalldata the Uniswap quote calldata returned by the SDK, to be sent to the router contract * @param callData the encoded instructions to be executed by the lock * * @return the bytes as returned by the execution on the lock * * @notice If the actual amount spent is less than the specified maximum amount, the remaining tokens will * be held by the Unlock contract */ function swapAndCall( address lock, address srcToken, uint amountInMax, address uniswapRouter, bytes memory swapCalldata, bytes memory callData ) public payable returns(bytes memory) { // check if lock exists (bool lockExists,,) = IUnlock(unlockAddress).locks(lock); if(!lockExists) { revert LockDoesntExist(lock); } // make sure if(uniswapRouters[uniswapRouter] != true) { revert UnautorizedRouter(uniswapRouter); } // get lock pricing address destToken = IPublicLock(lock).tokenAddress(); // get balances of UnlockSwapPurchaser before // if payments in ETH, substract the value sent by user to get actual balance uint balanceTokenDestBefore = destToken == address(0) ? getBalance(destToken) - msg.value : getBalance(destToken); uint balanceTokenSrcBefore = srcToken == address(0) ? getBalance(srcToken) - msg.value : getBalance(srcToken); if(srcToken != address(0)) { // Transfer the specified amount of src ERC20 to this contract TransferHelper.safeTransferFrom(srcToken, msg.sender, address(this), amountInMax); // Approve the router to spend src ERC20 TransferHelper.safeApprove(srcToken, uniswapRouter, amountInMax); // approve PERMIT2 to manipulate the token IERC20(srcToken).approve(permit2, amountInMax); } // issue PERMIT2 Allowance IPermit2(permit2).approve( srcToken, uniswapRouter, uint160(amountInMax), uint48(block.timestamp + 60) // expires after 1min ); // executes the swap (bool success, ) = uniswapRouter.call{ value: srcToken == address(0) ? msg.value : 0 }(swapCalldata); // make sure to catch Uniswap revert if(success == false) { revert SwapFailed(uniswapRouter, srcToken, destToken, amountInMax, swapCalldata); } // make sure balance is enough to buy key if(( destToken == address(0) ? getBalance(destToken) - msg.value : getBalance(destToken) ) < balanceTokenDestBefore + IPublicLock(lock).keyPrice()) { revert InsufficientBalance(); } // approve ERC20 to call the lock if(destToken != address(0)) { IMintableERC20(destToken).approve(lock, IPublicLock(lock).keyPrice()); } // call the lock (bool lockCallSuccess, bytes memory returnData) = lock.call{ value: destToken == address(0) ? IPublicLock(lock).keyPrice() : 0 }( callData ); if(lockCallSuccess == false) { revert LockCallFailed(); } // check that Unlock did not spend more than it received if( getBalance(srcToken) - balanceTokenSrcBefore < 0 || getBalance(destToken) - balanceTokenDestBefore < 0 ) { // balance too low revert UnauthorizedBalanceChange(); } // returns whatever the lock returned return returnData; } /** * This is used to send remaining tokens from swaps to the main unlock contract * @param tokenAddress the ERC20 contract address of the token to withdraw * or address(0) for native tokens */ function withdrawToUnlock(address tokenAddress) public { uint balance = getBalance(tokenAddress); if(tokenAddress != address(0)) { IERC20(tokenAddress).transfer(unlockAddress, balance); } else { (bool sent,) = payable(unlockAddress).call{value: balance}(""); if(sent == false) { revert WithdrawFailed(); } } } // required to withdraw WETH receive() external payable {} }
{ "optimizer": { "enabled": true, "runs": 80 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_unlockAddress","type":"address"},{"internalType":"address","name":"_permit2Address","type":"address"},{"internalType":"address[]","name":"_uniswapRouters","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"LockCallFailed","type":"error"},{"inputs":[{"internalType":"address","name":"lockAddress","type":"address"}],"name":"LockDoesntExist","type":"error"},{"inputs":[{"internalType":"address","name":"uniswapRouter","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"name":"SwapFailed","type":"error"},{"inputs":[],"name":"UnauthorizedBalanceChange","type":"error"},{"inputs":[{"internalType":"address","name":"routerAddress","type":"address"}],"name":"UnautorizedRouter","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lock","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSpent","type":"uint256"}],"name":"SwapCall","type":"event"},{"inputs":[],"name":"permit2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lock","type":"address"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address","name":"uniswapRouter","type":"address"},{"internalType":"bytes","name":"swapCalldata","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"}],"name":"swapAndCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"unlockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"withdrawToUnlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620011033803806200110383398101604081905262000034916200010a565b600080546001600160a01b038086166001600160a01b031992831617835560018054918616919092161790555b8151811015620000cd5760016002600084848151811062000086576200008662000204565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580620000c4816200021a565b91505062000061565b5050505062000242565b80516001600160a01b0381168114620000ef57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156200012057600080fd5b6200012b84620000d7565b925060206200013c818601620000d7565b60408601519093506001600160401b03808211156200015a57600080fd5b818701915087601f8301126200016f57600080fd5b815181811115620001845762000184620000f4565b8060051b604051601f19603f83011681018181108582111715620001ac57620001ac620000f4565b60405291825284820192508381018501918a831115620001cb57600080fd5b938501935b82851015620001f457620001e485620000d7565b84529385019392850192620001d0565b8096505050505050509250925092565b634e487b7160e01b600052603260045260246000fd5b6000600182016200023b57634e487b7160e01b600052601160045260246000fd5b5060010190565b610eb180620002526000396000f3fe6080604052600436106100435760003560e01c806302837f7b1461004f57806312261ee7146100715780635e8f4502146100a7578063b30929cd146100c757600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610b32565b6100e7565b005b34801561007d57600080fd5b50600154610091906001600160a01b031681565b60405161009e9190610b56565b60405180910390f35b6100ba6100b5366004610c0d565b6101f9565b60405161009e9190610d0d565b3480156100d357600080fd5b50600054610091906001600160a01b031681565b60006100f28261087b565b90506001600160a01b0382161561017f5760005460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261013792909116908590600401610d20565b6020604051808303816000875af1158015610156573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017a9190610d4e565b505050565b600080546040516001600160a01b039091169083908381818185875af1925050503d80600081146101cc576040519150601f19603f3d011682016040523d82523d6000602084013e6101d1565b606091505b509091505080151560000361017a57604051631d42c86760e21b815260040160405180910390fd5b60008054604051635de9a13760e01b8152606092916001600160a01b031690635de9a1379061022c908b90600401610b56565b606060405180830381865afa158015610249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026d9190610d69565b505090508061029a5787604051637421631960e11b81526004016102919190610b56565b60405180910390fd5b6001600160a01b03851660009081526002602052604090205460ff1615156001146102da578460405163f2f52fc960e01b81526004016102919190610b56565b6000886001600160a01b0316639d76ea586040518163ffffffff1660e01b8152600401602060405180830381865afa15801561031a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033e9190610d9e565b905060006001600160a01b0382161561035f5761035a8261087b565b610373565b346103698361087b565b6103739190610dd1565b905060006001600160a01b038a16156103945761038f8a61087b565b6103a8565b3461039e8b61087b565b6103a89190610dd1565b90506001600160a01b038a1615610449576103c58a33308c610906565b6103d08a898b610a10565b60015460405163095ea7b360e01b81526001600160a01b038c81169263095ea7b39261040492909116908d90600401610d20565b6020604051808303816000875af1158015610423573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104479190610d4e565b505b6001546001600160a01b03166387517c458b8a8c61046842603c610de8565b6040516001600160e01b031960e087901b1681526001600160a01b03948516600482015292841660248401529216604482015265ffffffffffff9091166064820152608401600060405180830381600087803b1580156104c757600080fd5b505af11580156104db573d6000803e3d6000fd5b5060009250506001600160a01b03808b1691508c16156104fc5760006104fe565b345b8960405161050c9190610e00565b60006040518083038185875af1925050503d8060008114610549576040519150601f19603f3d011682016040523d82523d6000602084013e61054e565b606091505b509091505080151560000361058057888b858c8b604051637bd486e960e11b8152600401610291959493929190610e1c565b8b6001600160a01b03166310e569736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190610e62565b6105ec9084610de8565b6001600160a01b03851615610609576106048561087b565b61061d565b346106138661087b565b61061d9190610dd1565b101561063c57604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b0384161561071f57836001600160a01b031663095ea7b38d8e6001600160a01b03166310e569736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bd9190610e62565b6040518363ffffffff1660e01b81526004016106da929190610d20565b6020604051808303816000875af11580156106f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071d9190610d4e565b505b6000806001600160a01b03808f169087161561073c57600061079e565b8e6001600160a01b03166310e569736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561077a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079e9190610e62565b8a6040516107ac9190610e00565b60006040518083038185875af1925050503d80600081146107e9576040519150601f19603f3d011682016040523d82523d6000602084013e6107ee565b606091505b50909250905081151560000361081757604051637772507160e11b815260040160405180910390fd5b6000846108238f61087b565b61082d9190610dd1565b108061084c57506000856108408861087b565b61084a9190610dd1565b105b1561086a5760405163392032cb60e21b815260040160405180910390fd5b9d9c50505050505050505050505050565b60006001600160a01b038216156108fe576040516370a0823160e01b81526001600160a01b038316906370a08231906108b8903090600401610b56565b602060405180830381865afa1580156108d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f99190610e62565b610900565b475b92915050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161096a9190610e00565b6000604051808303816000865af19150503d80600081146109a7576040519150601f19603f3d011682016040523d82523d6000602084013e6109ac565b606091505b50915091508180156109d65750805115806109d65750808060200190518101906109d69190610d4e565b610a085760405162461bcd60e51b815260206004820152600360248201526229aa2360e91b6044820152606401610291565b505050505050565b600080846001600160a01b031663095ea7b360e01b8585604051602401610a38929190610d20565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610a769190610e00565b6000604051808303816000865af19150503d8060008114610ab3576040519150601f19603f3d011682016040523d82523d6000602084013e610ab8565b606091505b5091509150818015610ae2575080511580610ae2575080806020019051810190610ae29190610d4e565b610b135760405162461bcd60e51b8152602060048201526002602482015261534160f01b6044820152606401610291565b5050505050565b6001600160a01b0381168114610b2f57600080fd5b50565b600060208284031215610b4457600080fd5b8135610b4f81610b1a565b9392505050565b6001600160a01b0391909116815260200190565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610b9157600080fd5b813567ffffffffffffffff80821115610bac57610bac610b6a565b604051601f8301601f19908116603f01168101908282118183101715610bd457610bd4610b6a565b81604052838152866020858801011115610bed57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060008060c08789031215610c2657600080fd5b8635610c3181610b1a565b95506020870135610c4181610b1a565b9450604087013593506060870135610c5881610b1a565b9250608087013567ffffffffffffffff80821115610c7557600080fd5b610c818a838b01610b80565b935060a0890135915080821115610c9757600080fd5b50610ca489828a01610b80565b9150509295509295509295565b60005b83811015610ccc578181015183820152602001610cb4565b83811115610cdb576000848401525b50505050565b60008151808452610cf9816020860160208601610cb1565b601f01601f19169290920160200192915050565b602081526000610b4f6020830184610ce1565b6001600160a01b03929092168252602082015260400190565b80518015158114610d4957600080fd5b919050565b600060208284031215610d6057600080fd5b610b4f82610d39565b600080600060608486031215610d7e57600080fd5b610d8784610d39565b925060208401519150604084015190509250925092565b600060208284031215610db057600080fd5b8151610b4f81610b1a565b634e487b7160e01b600052601160045260246000fd5b600082821015610de357610de3610dbb565b500390565b60008219821115610dfb57610dfb610dbb565b500190565b60008251610e12818460208701610cb1565b9190910192915050565b6001600160a01b0386811682528581166020830152841660408201526060810183905260a060808201819052600090610e5790830184610ce1565b979650505050505050565b600060208284031215610e7457600080fd5b505191905056fea2646970667358221220f15885891d83577bf265f3b7f85f96639bf1fa423670362f91f4c3a5827c933b64736f6c634300080d00330000000000000000000000001ff7e338d5e582138c46044dc238543ce555c963000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c73d61d192fb994157168fb56730fdec64c9cb8f0000000000000000000000005615cdab10dc425a742d643d949a7f474c01abc4
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001ff7e338d5e582138c46044dc238543ce555c963000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c73d61d192fb994157168fb56730fdec64c9cb8f0000000000000000000000005615cdab10dc425a742d643d949a7f474c01abc4
-----Decoded View---------------
Arg [0] : _unlockAddress (address): 0x1ff7e338d5e582138c46044dc238543ce555c963
Arg [1] : _permit2Address (address): 0x000000000022d473030f116ddee9f6b43ac78ba3
Arg [2] : _uniswapRouters (address[]): 0xc73d61d192fb994157168fb56730fdec64c9cb8f,0x5615cdab10dc425a742d643d949a7f474c01abc4
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000001ff7e338d5e582138c46044dc238543ce555c963
Arg [1] : 000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [4] : 000000000000000000000000c73d61d192fb994157168fb56730fdec64c9cb8f
Arg [5] : 0000000000000000000000005615cdab10dc425a742d643d949a7f474c01abc4
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.