More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
73897934 | 109 days ago | 0.76045523 MNT | ||||
73850681 | 111 days ago | 0.80243234 MNT | ||||
73807226 | 112 days ago | 4.01216174 MNT | ||||
73784489 | 112 days ago | 0.81165773 MNT | ||||
73784166 | 112 days ago | 0.81165773 MNT | ||||
73237332 | 125 days ago | 0.00771364 MNT | ||||
71770737 | 159 days ago | 0.27596673 MNT | ||||
71669387 | 161 days ago | 7.74255596 MNT | ||||
71669346 | 161 days ago | 7.88136352 MNT | ||||
71669254 | 161 days ago | 8.02284155 MNT | ||||
71669192 | 161 days ago | 8.45863413 MNT | ||||
71669096 | 161 days ago | 8.29829853 MNT | ||||
62142314 | 382 days ago | 0.37395282 MNT | ||||
61453728 | 398 days ago | 1.18799626 MNT | ||||
61358779 | 400 days ago | 1.28150996 MNT | ||||
61193529 | 404 days ago | 1.09429731 MNT | ||||
61088810 | 404 days ago | 0.49611178 MNT | ||||
61088524 | 404 days ago | 0.99325498 MNT | ||||
60717631 | 407 days ago | 0.94818029 MNT | ||||
60528742 | 408 days ago | 0.91897718 MNT | ||||
60318303 | 409 days ago | 0.93197551 MNT | ||||
60297752 | 409 days ago | 0.93601656 MNT | ||||
60288557 | 409 days ago | 0.93040946 MNT | ||||
60287293 | 409 days ago | 0.93022716 MNT | ||||
60285668 | 409 days ago | 0.93299335 MNT |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Tipping
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { IERC1155 } from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import { ITipping } from "./interfaces/ITipping.sol"; import { MultiAssetSender } from "./libs/MultiAssetSender.sol"; import { FeeCalculator } from "./libs/FeeCalculatorSimple.sol"; import { Batchable } from "./libs/Batchable.sol"; import { AssetType, FeeType } from "./enums/IDrissEnums.sol"; error tipping__withdraw__OnlyAdminCanWithdraw(); error unknown_function_selector(); /** * @title Tipping * @author Lennard (lennardevertz) * @custom:contributor Rafał Kalinowski <[email protected]> * @notice Tipping is a helper smart contract used for IDriss social media tipping functionality * @notice This simplified version does not use attestations or (chainlink) oracles for fee calculations */ contract Tipping is Ownable, ITipping, MultiAssetSender, FeeCalculator, Batchable, IERC165 { mapping(address => bool) public admins; mapping(address => bool) public publicGoods; event TipMessage( address indexed recipientAddress, string message, address indexed sender, address indexed tokenAddress, uint256 amount, uint256 fee ); constructor() { admins[msg.sender] = true; FEE_TYPE_MAPPING[AssetType.Coin] = FeeType.Percentage; FEE_TYPE_MAPPING[AssetType.Token] = FeeType.Percentage; FEE_TYPE_MAPPING[AssetType.NFT] = FeeType.Constant; FEE_TYPE_MAPPING[AssetType.ERC1155] = FeeType.Constant; } /** * @notice Send native currency tip, charging a small fee */ function sendTo( address _recipient, uint256, // amount is used only for multicall string memory _message ) external payable override { uint256 msgValue = _MSG_VALUE > 0 ? _MSG_VALUE : msg.value; uint256 paymentValue; if (publicGoods[_recipient]) { paymentValue = msgValue; } else { (, paymentValue) = _splitPayment(msgValue, AssetType.Coin); } _sendCoin(_recipient, paymentValue); emit TipMessage(_recipient, _message, msg.sender, address(0), paymentValue, msgValue-paymentValue); } /** * @notice Send a tip in ERC20 token, charging a small fee */ function sendTokenTo( address _recipient, uint256 _amount, address _tokenContractAddr, string memory _message ) external payable override { uint256 paymentValue; if (publicGoods[_recipient]) { paymentValue = _amount; } else { (, paymentValue) = _splitPayment(_amount, AssetType.Token); } _sendTokenAssetFrom(_amount, msg.sender, address(this), _tokenContractAddr); _sendTokenAsset(paymentValue, _recipient, _tokenContractAddr); emit TipMessage(_recipient, _message, msg.sender, _tokenContractAddr, paymentValue, _amount-paymentValue); } /** * @notice Send a tip in ERC721 token, charging a small $ fee */ function sendERC721To( address _recipient, uint256 _tokenId, address _nftContractAddress, string memory _message ) external payable override { // we use it just to revert when value is too small uint256 msgValue = _MSG_VALUE > 0 ? _MSG_VALUE : msg.value; (uint256 fee,) = _splitPayment(msgValue, AssetType.NFT); _sendNFTAsset(_tokenId, msg.sender, _recipient, _nftContractAddress); emit TipMessage(_recipient, _message, msg.sender, _nftContractAddress, msgValue, fee); } /** * @notice Send a tip in ERC721 token, charging a small $ fee */ function sendERC1155To( address _recipient, uint256 _assetId, uint256 _amount, address _assetContractAddress, string memory _message ) external payable override { // we use it just to revert when value is too small uint256 msgValue = _MSG_VALUE > 0 ? _MSG_VALUE : msg.value; (uint256 fee,) = _splitPayment(msgValue, AssetType.ERC1155); _sendERC1155Asset(_assetId, _amount, msg.sender, _recipient, _assetContractAddress); emit TipMessage(_recipient, _message, msg.sender, _assetContractAddress, msgValue, fee); } /** * @notice Withdraw native currency transfer fees */ function withdraw() external override onlyAdminCanWithdraw { (bool success, ) = msg.sender.call{value: address(this).balance}(""); require(success, "Failed to withdraw."); } modifier onlyAdminCanWithdraw() { if (admins[msg.sender] != true) { revert tipping__withdraw__OnlyAdminCanWithdraw(); } _; } /** * @notice Withdraw ERC20 transfer fees */ function withdrawToken(address _tokenContract) external override onlyAdminCanWithdraw { IERC20 withdrawTC = IERC20(_tokenContract); withdrawTC.transfer(msg.sender, withdrawTC.balanceOf(address(this))); } /** * @notice Add admin with priviledged access */ function addAdmin(address _adminAddress) external override onlyOwner { admins[_adminAddress] = true; } /** * @notice Remove admin */ function deleteAdmin(address _adminAddress) external override onlyOwner { admins[_adminAddress] = false; } /** * @notice Add public goods address with priviledged fee structure */ function addPublicGood(address _publicGoodAddress) external onlyOwner { publicGoods[_publicGoodAddress] = true; } /** * @notice Remove public goods address */ function deletePublicGood(address _publicGoodAddress) external onlyOwner { delete publicGoods[_publicGoodAddress]; } /** * @notice This is a function that allows for multicall * @param _calls An array of inputs for each call. * @dev calls Batchable::callBatch */ function batch(bytes[] calldata _calls) external payable { batchCall(_calls); } function isMsgValueOverride(bytes4 _selector) override pure internal returns (bool) { return _selector == this.sendTo.selector || _selector == this.sendTokenTo.selector || _selector == this.sendERC721To.selector || _selector == this.sendERC1155To.selector ; } function calculateMsgValueForACall(bytes4 _selector, bytes memory _calldata) override view internal returns (uint256) { uint256 currentCallPriceAmount; if (_selector == this.sendTo.selector) { assembly { currentCallPriceAmount := mload(add(_calldata, 68)) } } else if (_selector == this.sendTokenTo.selector) { currentCallPriceAmount = getPaymentFee(0, AssetType.Token); } else if (_selector == this.sendERC721To.selector) { currentCallPriceAmount = getPaymentFee(0, AssetType.NFT); } else if (_selector == this.sendERC1155To.selector) { currentCallPriceAmount = getPaymentFee(0, AssetType.ERC1155); } else { revert unknown_function_selector(); } return currentCallPriceAmount; } /* * @notice Always reverts. By default Ownable supports renouncing ownership, that is setting owner to address 0. * However in this case it would disallow receiving payment fees by anyone. */ function renounceOwnership() public override view onlyOwner { revert("Operation not supported"); } /** * @notice ERC165 interface function implementation, listing all supported interfaces */ function supportsInterface (bytes4 interfaceId) public pure override returns (bool) { return interfaceId == type(IERC165).interfaceId || interfaceId == type(ITipping).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; enum AssetType { Coin, Token, NFT, ERC1155 } /** * Percentage - constant percentage, e.g. 1% of the msg.value * PercentageOrConstantMaximum - get msg.value percentage, or constant dollar value, depending on what is bigger * Constant - constant dollar value, e.g. $1 - uses price Oracle */ enum FeeType { Percentage, PercentageOrConstantMaximum, Constant }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import { AssetType } from "../enums/IDrissEnums.sol"; interface ITipping { function sendTo( address _recipient, uint256 _amount, string memory _message ) external payable; function sendTokenTo( address _recipient, uint256 _amount, address _tokenContractAddr, string memory _message ) external payable; function sendERC721To( address _recipient, uint256 _assetId, address _nftContractAddress, string memory _message ) external payable; function sendERC1155To( address _recipient, uint256 _assetId, uint256 _amount, address _nftContractAddress, string memory _message ) external payable; function withdraw() external; function withdrawToken(address _tokenContract) external; function addAdmin(address _adminAddress) external; function deleteAdmin(address _adminAddress) external; function addPublicGood(address _publicGoodAddress) external; function deletePublicGood(address _publicGoodAddress) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @title Batchable * @author Rafał Kalinowski <[email protected]> * @dev This is BoringBatchable based function with a small twist: because delgatecall passes msg.value * on each call, it may introduce double spending issue. To avoid that, we handle cases when msg.value matters separately. * Please note that you'll have to pass msg.value in amount field for native currency per each call * Additionally, please keep in mind that currently you cannot put payable and nonpayable calls in the same batch - * - nonpayable functions will revert when receiving money */ abstract contract Batchable { uint256 internal _MSG_VALUE; uint256 internal constant _BATCH_NOT_ENTERED = 1; uint256 internal constant _BATCH_ENTERED = 2; uint256 internal _batchStatus; error BatchError(bytes innerError); constructor() { _batchStatus = _BATCH_NOT_ENTERED; } /** * @notice This function allows batched call to self (this contract). * @param _calls An array of inputs for each call. * @dev - it sets _MSG_VALUE variable for a call, if function is payable * check if the function is payable is done in your implementation of function `isMsgValueOverride()` * and _MSG_VALUE is set based on your `calculateMsgValueForACall()` implementation */ // F1: External is ok here because this is the batch function, adding it to a batch makes no sense // F2: Calls in the batch may be payable, delegatecall operates in the same context, so each call in the batch has access to msg.value // C3: The length of the loop is fully under user control, so can't be exploited // C7: Delegatecall is used on the same contract, and there is reentrancy guard in place function batchCall(bytes[] calldata _calls) internal { // bacause we already have reentrancy guard for functions, we set second kind of reentrancy guard require(_batchStatus != _BATCH_ENTERED, "ReentrancyGuard: reentrant call"); uint256 msgValueSentAcc; _batchStatus = _BATCH_ENTERED; for (uint256 i = 0; i < _calls.length; i++) { bool success; bytes memory result; bytes memory data = _calls[i]; bytes4 sig; assembly { sig := mload(add(data, add(0x20, 0))) } // set proper msg.value for payable function, as delegatecall can introduce double spending if (isMsgValueOverride(sig)) { uint256 currentCallPriceAmount = calculateMsgValueForACall(sig, data); _MSG_VALUE = currentCallPriceAmount; msgValueSentAcc += currentCallPriceAmount; require (msgValueSentAcc <= msg.value, "Can't send more than msg.value"); (success, result) = address(this).delegatecall(data); _MSG_VALUE = 0; } else { (success, result) = address(this).delegatecall(data); } if (!success) { _getRevertMsg(result); } } _batchStatus = _BATCH_NOT_ENTERED; } /** * @notice This is part of BoringBatchable contract * https://github.com/boringcrypto/BoringSolidity/blob/master/contracts/BoringBatchable.sol * @dev Helper function to extract a useful revert message from a failed call. * If the returned data is malformed or not correctly abi encoded then this call can fail itself. */ function _getRevertMsg(bytes memory _returnData) internal pure { // If the _res length is less than 68, then // the transaction failed with custom error or silently (without a revert message) if (_returnData.length < 68) revert BatchError(_returnData); assembly { // Slice the sighash. _returnData := add(_returnData, 0x04) } revert(abi.decode(_returnData, (string))); // All that remains is the revert string } /** * @notice Checks if a function is payable, i.e. should _MSG_VALUE be set * @param _selector function selector * @dev Write your logic checking if a function is payable, e.g. this.<function-name>.selector == _selector * WARNING - if you, or someone else if able to construct the same selector for a malicious function (which is not that hard), * the logic may break and the msg.value may be exploited */ function isMsgValueOverride(bytes4 _selector) virtual pure internal returns (bool); /** * @notice Calculates msg.value that should be sent with a call * @param _selector function selector * @param _calldata single call encoded data * @dev You should probably decode function parameters and check what value should be passed */ function calculateMsgValueForACall(bytes4 _selector, bytes memory _calldata) virtual view internal returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import { AssetType, FeeType } from "../enums/IDrissEnums.sol"; /** * @title FeeCalculator * @author Rafał Kalinowski <[email protected]> * @custom:contributor Lennard (levertz) * @notice This is an utility contract for calculating a fee * @notice In this simlified version, we don't use (chainlink) oracles, but a constant (adjustable) fee */ contract FeeCalculator is Ownable { uint256 public constant PAYMENT_FEE_SLIPPAGE_PERCENT = 5; uint256 public PAYMENT_FEE_PERCENTAGE = 10; uint256 public PAYMENT_FEE_PERCENTAGE_DENOMINATOR = 1000; uint256 public MINIMAL_PAYMENT_FEE = 500000000000000; // you have to pass your desired fee types in a constructor deriving this contract mapping (AssetType => FeeType) FEE_TYPE_MAPPING; constructor() { } /** * @notice Calculates payment fee * @param _value - payment value * @param _assetType - asset type, required as ERC20 & ERC721 only take minimal fee * @return fee - processing fee, few percent of slippage is allowed */ function getPaymentFee(uint256 _value, AssetType _assetType) public view returns (uint256) { uint256 minimumPaymentFee = _getMinimumFee(); uint256 percentageFee = _getPercentageFee(_value); FeeType feeType = FEE_TYPE_MAPPING[_assetType]; if (feeType == FeeType.Constant) { return minimumPaymentFee; } else if (feeType == FeeType.Percentage) { return percentageFee; } // default case - PercentageOrConstantMaximum if (percentageFee > minimumPaymentFee) return percentageFee; else return minimumPaymentFee; } function _getMinimumFee() internal view returns (uint256) { return MINIMAL_PAYMENT_FEE; } function _getPercentageFee(uint256 _value) internal view returns (uint256) { return (_value * PAYMENT_FEE_PERCENTAGE) / PAYMENT_FEE_PERCENTAGE_DENOMINATOR; } /** * @notice Calculates value of a fee from sent msg.value * @param _valueToSplit - payment value, taken from msg.value * @param _assetType - asset type, as there may be different calculation logic for each type * @return fee - processing fee, few percent of slippage is allowed * @return value - payment value after substracting fee */ function _splitPayment(uint256 _valueToSplit, AssetType _assetType) internal view returns (uint256 fee, uint256 value) { uint256 minimalPaymentFee = _getMinimumFee(); uint256 paymentFee = getPaymentFee(_valueToSplit, _assetType); // we accept slippage of native coin price if fee type is not percentage - it this case we always get % no matter dollar price if (FEE_TYPE_MAPPING[_assetType] != FeeType.Percentage && _valueToSplit >= minimalPaymentFee * (100 - PAYMENT_FEE_SLIPPAGE_PERCENT) / 100 && _valueToSplit <= minimalPaymentFee) { fee = _valueToSplit; } else { fee = paymentFee; } require (_valueToSplit >= fee, "Value sent is smaller than minimal fee."); value = _valueToSplit - fee; } /** * @notice adjust payment fee percentage for big native currency transfers * @dev Solidity is not good when it comes to handling floats. We use denominator then, * e.g. to set payment fee to 1.5% , just pass paymentFee = 15 & denominator = 1000 => 15 / 1000 = 0.015 = 1.5% */ function changePaymentFeePercentage (uint256 _paymentFeePercentage, uint256 _paymentFeeDenominator) external onlyOwner { require(_paymentFeePercentage > 0, "Payment fee has to be bigger than 0"); require(_paymentFeeDenominator > 0, "Payment fee denominator has to be bigger than 0"); PAYMENT_FEE_PERCENTAGE = _paymentFeePercentage; PAYMENT_FEE_PERCENTAGE_DENOMINATOR = _paymentFeeDenominator; } /** * @notice adjust minimal payment fee for all asset transfers */ function changeMinimalPaymentFee (uint256 _minimalPaymentFee) external onlyOwner { require(_minimalPaymentFee > 0, "Payment fee has to be bigger than 0"); MINIMAL_PAYMENT_FEE = _minimalPaymentFee; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; /** * @title MultiAssetSender * @author Rafał Kalinowski <[email protected]> * @notice This is an utility contract for sending different kind of assets * @dev Please note that you should make reentrancy check yourself */ contract MultiAssetSender { constructor() { } /** * @notice Wrapper for sending native Coin via call function * @dev When using this function please make sure to not send it to anyone, verify the * address in IDriss registry */ function _sendCoin (address _to, uint256 _amount) internal { (bool sent, ) = payable(_to).call{value: _amount}(""); require(sent, "Failed to send"); } /** * @notice Wrapper for sending single ERC1155 asset * @dev due to how approval in ERC1155 standard is handled, the smart contract has to ask for permissions to manage * ALL tokens "for simplicity"... Hence, it has to be done before calling function that transfers the token * to smart contract, and revoked afterwards */ function _sendERC1155AssetBatch ( uint256[] memory _assetIds, uint256[] memory _amounts, address _from, address _to, address _contractAddress ) internal { IERC1155 nft = IERC1155(_contractAddress); nft.safeBatchTransferFrom(_from, _to, _assetIds, _amounts, ""); } /** * @notice Wrapper for sending multiple ERC1155 assets * @dev due to how approval in ERC1155 standard is handled, the smart contract has to ask for permissions to manage * ALL tokens "for simplicity"... Hence, it has to be done before calling function that transfers the token * to smart contract, and revoked afterwards */ function _sendERC1155Asset ( uint256 _assetId, uint256 _amount, address _from, address _to, address _contractAddress ) internal { IERC1155 nft = IERC1155(_contractAddress); nft.safeTransferFrom(_from, _to, _assetId, _amount, ""); } /** * @notice Wrapper for sending NFT asset */ function _sendNFTAsset ( uint256 _assetIds, address _from, address _to, address _contractAddress ) internal { IERC721 nft = IERC721(_contractAddress); nft.safeTransferFrom(_from, _to, _assetIds, ""); } /** * @notice Wrapper for sending NFT asset with additional checks and iteraton over an array */ function _sendNFTAssetBatch ( uint256[] memory _assetIds, address _from, address _to, address _contractAddress ) internal { require(_assetIds.length > 0, "Nothing to send"); IERC721 nft = IERC721(_contractAddress); for (uint256 i = 0; i < _assetIds.length; ++i) { nft.safeTransferFrom(_from, _to, _assetIds[i], ""); } } /** * @notice Wrapper for sending ERC20 Token asset with additional checks */ function _sendTokenAsset ( uint256 _amount, address _to, address _contractAddress ) internal { IERC20 token = IERC20(_contractAddress); bool sent = token.transfer(_to, _amount); require(sent, "Failed to transfer token"); } /** * @notice Wrapper for sending ERC20 token from specific account with additional checks and iteraton over an array */ function _sendTokenAssetFrom ( uint256 _amount, address _from, address _to, address _contractAddress ) internal { IERC20 token = IERC20(_contractAddress); bool sent = token.transferFrom(_from, _to, _amount); require(sent, "Failed to transfer token"); } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"innerError","type":"bytes"}],"name":"BatchError","type":"error"},{"inputs":[],"name":"tipping__withdraw__OnlyAdminCanWithdraw","type":"error"},{"inputs":[],"name":"unknown_function_selector","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipientAddress","type":"address"},{"indexed":false,"internalType":"string","name":"message","type":"string"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"TipMessage","type":"event"},{"inputs":[],"name":"MINIMAL_PAYMENT_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_FEE_PERCENTAGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_FEE_PERCENTAGE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_FEE_SLIPPAGE_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_adminAddress","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_publicGoodAddress","type":"address"}],"name":"addPublicGood","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_calls","type":"bytes[]"}],"name":"batch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minimalPaymentFee","type":"uint256"}],"name":"changeMinimalPaymentFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_paymentFeePercentage","type":"uint256"},{"internalType":"uint256","name":"_paymentFeeDenominator","type":"uint256"}],"name":"changePaymentFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adminAddress","type":"address"}],"name":"deleteAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_publicGoodAddress","type":"address"}],"name":"deletePublicGood","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"enum AssetType","name":"_assetType","type":"uint8"}],"name":"getPaymentFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicGoods","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_assetId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_assetContractAddress","type":"address"},{"internalType":"string","name":"_message","type":"string"}],"name":"sendERC1155To","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"string","name":"_message","type":"string"}],"name":"sendERC721To","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"string","name":"_message","type":"string"}],"name":"sendTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_tokenContractAddr","type":"address"},{"internalType":"string","name":"_message","type":"string"}],"name":"sendTokenTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600a6001556103e86002556601c6bf526340006003553480156200002757600080fd5b50620000486200003c6200025460201b60201c565b6200025c60201b60201c565b60016006819055506001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600060046000806003811115620000c457620000c362000320565b5b6003811115620000d957620000d862000320565b5b815260200190815260200160002060006101000a81548160ff021916908360028111156200010c576200010b62000320565b5b0217905550600060046000600160038111156200012e576200012d62000320565b5b600381111562000143576200014262000320565b5b815260200190815260200160002060006101000a81548160ff0219169083600281111562000176576200017562000320565b5b02179055506002600460006002600381111562000198576200019762000320565b5b6003811115620001ad57620001ac62000320565b5b815260200190815260200160002060006101000a81548160ff02191690836002811115620001e057620001df62000320565b5b021790555060026004600060038081111562000201576200020062000320565b5b600381111562000216576200021562000320565b5b815260200190815260200160002060006101000a81548160ff0219169083600281111562000249576200024862000320565b5b02179055506200034f565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b612f61806200035f6000396000f3fe60806040526004361061014b5760003560e01c80635cfdb086116100b6578063894760691161006f578063894760691461041e5780638d157db8146104475780638da5cb5b146104635780639cd6aa4c1461048e578063b20d0bff146104cb578063f2fde38b146104f45761014b565b80635cfdb08614610331578063704802751461035a5780637129607a14610383578063715018a61461039f57806382313032146103b657806383a4c7e1146103f35761014b565b806327e1f7df1161010857806327e1f7df1461024457806330ae06e01461026d5780633ccfd60b1461029657806341dfeca5146102ad578063429b62e5146102c95780635c73f163146103065761014b565b806301ffc9a71461015057806303f613dc1461018d5780630728c7d2146101b85780630f7f630a146101e157806316e491451461020c5780631e897afb14610228575b600080fd5b34801561015c57600080fd5b5061017760048036038101906101729190611d7b565b61051d565b6040516101849190611dc3565b60405180910390f35b34801561019957600080fd5b506101a26105ef565b6040516101af9190611df7565b60405180910390f35b3480156101c457600080fd5b506101df60048036038101906101da9190611e3e565b6105f5565b005b3480156101ed57600080fd5b506101f6610695565b6040516102039190611df7565b60405180910390f35b61022660048036038101906102219190612022565b61069b565b005b610242600480360381019061023d91906120f1565b6107bd565b005b34801561025057600080fd5b5061026b6004803603810190610266919061213e565b6107cb565b005b34801561027957600080fd5b50610294600480360381019061028f919061216b565b61082e565b005b3480156102a257600080fd5b506102ab610883565b005b6102c760048036038101906102c29190612198565b6109bc565b005b3480156102d557600080fd5b506102f060048036038101906102eb919061213e565b610ad3565b6040516102fd9190611dc3565b60405180910390f35b34801561031257600080fd5b5061031b610af3565b6040516103289190611df7565b60405180910390f35b34801561033d57600080fd5b506103586004803603810190610353919061213e565b610af9565b005b34801561036657600080fd5b50610381600480360381019061037c919061213e565b610b5c565b005b61039d6004803603810190610398919061221b565b610bbf565b005b3480156103ab57600080fd5b506103b4610c7c565b005b3480156103c257600080fd5b506103dd60048036038101906103d8919061213e565b610cbf565b6040516103ea9190611dc3565b60405180910390f35b3480156103ff57600080fd5b50610408610cdf565b6040516104159190611df7565b60405180910390f35b34801561042a57600080fd5b506104456004803603810190610440919061213e565b610ce4565b005b610461600480360381019061045c9190612198565b610e6f565b005b34801561046f57600080fd5b50610478610f2a565b60405161048591906122c1565b60405180910390f35b34801561049a57600080fd5b506104b560048036038101906104b09190612301565b610f53565b6040516104c29190611df7565b60405180910390f35b3480156104d757600080fd5b506104f260048036038101906104ed919061213e565b611043565b005b34801561050057600080fd5b5061051b6004803603810190610516919061213e565b61109d565b005b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105e857507fa7d69893000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60025481565b6105fd611120565b60008211610640576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610637906123c4565b60405180910390fd5b60008111610683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161067a90612456565b60405180910390fd5b81600181905550806002819055505050565b60035481565b600080600554116106ac57346106b0565b6005545b90506000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561070e57819050610720565b61071982600061119e565b9050809150505b61072a85826112cf565b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f06961b35a44f36e67b4d43a3b991e1f866c108a1417c6a986d4ba271b32cefe78685868861079f91906124a5565b6040516107ae93929190612547565b60405180910390a45050505050565b6107c78282611380565b5050565b6107d3611120565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610836611120565b60008111610879576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610870906123c4565b60405180910390fd5b8060038190555050565b60011515600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151461090d576040517f3db4b39200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff1647604051610933906125b6565b60006040518083038185875af1925050503d8060008114610970576040519150601f19603f3d011682016040523d82523d6000602084013e610975565b606091505b50509050806109b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109b090612617565b60405180910390fd5b50565b6000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610a1857839050610a2a565b610a2384600161119e565b9050809150505b610a36843330866115eb565b610a418186856116bc565b8273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f06961b35a44f36e67b4d43a3b991e1f866c108a1417c6a986d4ba271b32cefe78585868a610ab591906124a5565b604051610ac493929190612547565b60405180910390a45050505050565b60076020528060005260406000206000915054906101000a900460ff1681565b60015481565b610b01611120565b6001600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610b64611120565b6001600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008060055411610bd05734610bd4565b6005545b90506000610be382600361119e565b509050610bf38686338a8861178a565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f06961b35a44f36e67b4d43a3b991e1f866c108a1417c6a986d4ba271b32cefe7868686604051610c6b93929190612547565b60405180910390a450505050505050565b610c84611120565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb690612683565b60405180910390fd5b60086020528060005260406000206000915054906101000a900460ff1681565b600581565b60011515600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514610d6e576040517f3db4b39200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008190508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610dc991906122c1565b602060405180830381865afa158015610de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0a91906126b8565b6040518363ffffffff1660e01b8152600401610e279291906126e5565b6020604051808303816000875af1158015610e46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6a919061273a565b505050565b60008060055411610e805734610e84565b6005545b90506000610e9382600261119e565b509050610ea285338887611808565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f06961b35a44f36e67b4d43a3b991e1f866c108a1417c6a986d4ba271b32cefe7868686604051610f1a93929190612547565b60405180910390a4505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080610f5e611883565b90506000610f6b8561188d565b9050600060046000866003811115610f8657610f85612767565b5b6003811115610f9857610f97612767565b5b815260200190815260200160002060009054906101000a900460ff169050600280811115610fc957610fc8612767565b5b816002811115610fdc57610fdb612767565b5b03610fec5782935050505061103d565b6000600281111561100057610fff612767565b5b81600281111561101357611012612767565b5b036110235781935050505061103d565b828211156110365781935050505061103d565b8293505050505b92915050565b61104b611120565b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff021916905550565b6110a5611120565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611114576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110b90612808565b60405180910390fd5b61111d816118b1565b50565b611128611975565b73ffffffffffffffffffffffffffffffffffffffff16611146610f2a565b73ffffffffffffffffffffffffffffffffffffffff161461119c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119390612874565b60405180910390fd5b565b60008060006111ab611883565b905060006111b98686610f53565b9050600060028111156111cf576111ce612767565b5b600460008760038111156111e6576111e5612767565b5b60038111156111f8576111f7612767565b5b815260200190815260200160002060009054906101000a900460ff16600281111561122657611225612767565b5b14158015611258575060646005606461123f91906124a5565b8361124a9190612894565b6112549190612905565b8610155b80156112645750818611155b1561127157859350611275565b8093505b838610156112b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112af906129a8565b60405180910390fd5b83866112c491906124a5565b925050509250929050565b60008273ffffffffffffffffffffffffffffffffffffffff16826040516112f5906125b6565b60006040518083038185875af1925050503d8060008114611332576040519150601f19603f3d011682016040523d82523d6000602084013e611337565b606091505b505090508061137b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137290612a14565b60405180910390fd5b505050565b6002600654036113c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bc90612a80565b60405180910390fd5b6000600260068190555060005b838390508110156115dd576000606060008686858181106113f6576113f5612aa0565b5b90506020028101906114089190612ade565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060008060200182015190506114618161197d565b156115485760006114728284611abb565b90508060058190555080876114879190612b41565b9650348711156114cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c390612bc1565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16836040516114f19190612c1d565b600060405180830381855af49150503d806000811461152c576040519150601f19603f3d011682016040523d82523d6000602084013e611531565b606091505b5080955081965050506000600581905550506115b7565b3073ffffffffffffffffffffffffffffffffffffffff168260405161156d9190612c1d565b600060405180830381855af49150503d80600081146115a8576040519150601f19603f3d011682016040523d82523d6000602084013e6115ad565b606091505b5080945081955050505b836115c6576115c583611c72565b5b5050505080806115d590612c34565b9150506113d2565b506001600681905550505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166323b872dd8686896040518463ffffffff1660e01b815260040161162f93929190612c7c565b6020604051808303816000875af115801561164e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611672919061273a565b9050806116b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ab90612cff565b60405180910390fd5b505050505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85876040518363ffffffff1660e01b81526004016116fe9291906126e5565b6020604051808303816000875af115801561171d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611741919061273a565b905080611783576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177a90612cff565b60405180910390fd5b5050505050565b60008190508073ffffffffffffffffffffffffffffffffffffffff1663f242432a858589896040518563ffffffff1660e01b81526004016117ce9493929190612d53565b600060405180830381600087803b1580156117e857600080fd5b505af11580156117fc573d6000803e3d6000fd5b50505050505050505050565b60008190508073ffffffffffffffffffffffffffffffffffffffff1663b88d4fde8585886040518463ffffffff1660e01b815260040161184a93929190612dab565b600060405180830381600087803b15801561186457600080fd5b505af1158015611878573d6000803e3d6000fd5b505050505050505050565b6000600354905090565b6000600254600154836118a09190612894565b6118aa9190612905565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b60006316e4914560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a1657506341dfeca560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611a655750638d157db860e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611ab45750637129607a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000806316e4914560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611b165760448301519050611c68565b6341dfeca560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611b7557611b6e60006001610f53565b9050611c67565b638d157db860e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611bd457611bcd60006002610f53565b9050611c66565b637129607a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611c3357611c2c60006003610f53565b9050611c65565b6040517f2f4aeaf500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b5b8091505092915050565b604481511015611cb957806040517fd9354485000000000000000000000000000000000000000000000000000000008152600401611cb09190612e2e565b60405180910390fd5b60048101905080806020019051810190611cd39190612ec0565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d069190612f09565b60405180910390fd5b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611d5881611d23565b8114611d6357600080fd5b50565b600081359050611d7581611d4f565b92915050565b600060208284031215611d9157611d90611d19565b5b6000611d9f84828501611d66565b91505092915050565b60008115159050919050565b611dbd81611da8565b82525050565b6000602082019050611dd86000830184611db4565b92915050565b6000819050919050565b611df181611dde565b82525050565b6000602082019050611e0c6000830184611de8565b92915050565b611e1b81611dde565b8114611e2657600080fd5b50565b600081359050611e3881611e12565b92915050565b60008060408385031215611e5557611e54611d19565b5b6000611e6385828601611e29565b9250506020611e7485828601611e29565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611ea982611e7e565b9050919050565b611eb981611e9e565b8114611ec457600080fd5b50565b600081359050611ed681611eb0565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611f2f82611ee6565b810181811067ffffffffffffffff82111715611f4e57611f4d611ef7565b5b80604052505050565b6000611f61611d0f565b9050611f6d8282611f26565b919050565b600067ffffffffffffffff821115611f8d57611f8c611ef7565b5b611f9682611ee6565b9050602081019050919050565b82818337600083830152505050565b6000611fc5611fc084611f72565b611f57565b905082815260208101848484011115611fe157611fe0611ee1565b5b611fec848285611fa3565b509392505050565b600082601f83011261200957612008611edc565b5b8135612019848260208601611fb2565b91505092915050565b60008060006060848603121561203b5761203a611d19565b5b600061204986828701611ec7565b935050602061205a86828701611e29565b925050604084013567ffffffffffffffff81111561207b5761207a611d1e565b5b61208786828701611ff4565b9150509250925092565b600080fd5b600080fd5b60008083601f8401126120b1576120b0611edc565b5b8235905067ffffffffffffffff8111156120ce576120cd612091565b5b6020830191508360208202830111156120ea576120e9612096565b5b9250929050565b6000806020838503121561210857612107611d19565b5b600083013567ffffffffffffffff81111561212657612125611d1e565b5b6121328582860161209b565b92509250509250929050565b60006020828403121561215457612153611d19565b5b600061216284828501611ec7565b91505092915050565b60006020828403121561218157612180611d19565b5b600061218f84828501611e29565b91505092915050565b600080600080608085870312156121b2576121b1611d19565b5b60006121c087828801611ec7565b94505060206121d187828801611e29565b93505060406121e287828801611ec7565b925050606085013567ffffffffffffffff81111561220357612202611d1e565b5b61220f87828801611ff4565b91505092959194509250565b600080600080600060a0868803121561223757612236611d19565b5b600061224588828901611ec7565b955050602061225688828901611e29565b945050604061226788828901611e29565b935050606061227888828901611ec7565b925050608086013567ffffffffffffffff81111561229957612298611d1e565b5b6122a588828901611ff4565b9150509295509295909350565b6122bb81611e9e565b82525050565b60006020820190506122d660008301846122b2565b92915050565b600481106122e957600080fd5b50565b6000813590506122fb816122dc565b92915050565b6000806040838503121561231857612317611d19565b5b600061232685828601611e29565b9250506020612337858286016122ec565b9150509250929050565b600082825260208201905092915050565b7f5061796d656e74206665652068617320746f206265206269676765722074686160008201527f6e20300000000000000000000000000000000000000000000000000000000000602082015250565b60006123ae602383612341565b91506123b982612352565b604082019050919050565b600060208201905081810360008301526123dd816123a1565b9050919050565b7f5061796d656e74206665652064656e6f6d696e61746f722068617320746f206260008201527f6520626967676572207468616e20300000000000000000000000000000000000602082015250565b6000612440602f83612341565b915061244b826123e4565b604082019050919050565b6000602082019050818103600083015261246f81612433565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006124b082611dde565b91506124bb83611dde565b92508282039050818111156124d3576124d2612476565b5b92915050565b600081519050919050565b60005b838110156125025780820151818401526020810190506124e7565b60008484015250505050565b6000612519826124d9565b6125238185612341565b93506125338185602086016124e4565b61253c81611ee6565b840191505092915050565b60006060820190508181036000830152612561818661250e565b90506125706020830185611de8565b61257d6040830184611de8565b949350505050565b600081905092915050565b50565b60006125a0600083612585565b91506125ab82612590565b600082019050919050565b60006125c182612593565b9150819050919050565b7f4661696c656420746f2077697468647261772e00000000000000000000000000600082015250565b6000612601601383612341565b915061260c826125cb565b602082019050919050565b60006020820190508181036000830152612630816125f4565b9050919050565b7f4f7065726174696f6e206e6f7420737570706f72746564000000000000000000600082015250565b600061266d601783612341565b915061267882612637565b602082019050919050565b6000602082019050818103600083015261269c81612660565b9050919050565b6000815190506126b281611e12565b92915050565b6000602082840312156126ce576126cd611d19565b5b60006126dc848285016126a3565b91505092915050565b60006040820190506126fa60008301856122b2565b6127076020830184611de8565b9392505050565b61271781611da8565b811461272257600080fd5b50565b6000815190506127348161270e565b92915050565b6000602082840312156127505761274f611d19565b5b600061275e84828501612725565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006127f2602683612341565b91506127fd82612796565b604082019050919050565b60006020820190508181036000830152612821816127e5565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061285e602083612341565b915061286982612828565b602082019050919050565b6000602082019050818103600083015261288d81612851565b9050919050565b600061289f82611dde565b91506128aa83611dde565b92508282026128b881611dde565b915082820484148315176128cf576128ce612476565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061291082611dde565b915061291b83611dde565b92508261292b5761292a6128d6565b5b828204905092915050565b7f56616c75652073656e7420697320736d616c6c6572207468616e206d696e696d60008201527f616c206665652e00000000000000000000000000000000000000000000000000602082015250565b6000612992602783612341565b915061299d82612936565b604082019050919050565b600060208201905081810360008301526129c181612985565b9050919050565b7f4661696c656420746f2073656e64000000000000000000000000000000000000600082015250565b60006129fe600e83612341565b9150612a09826129c8565b602082019050919050565b60006020820190508181036000830152612a2d816129f1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a6a601f83612341565b9150612a7582612a34565b602082019050919050565b60006020820190508181036000830152612a9981612a5d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112612afb57612afa612acf565b5b80840192508235915067ffffffffffffffff821115612b1d57612b1c612ad4565b5b602083019250600182023603831315612b3957612b38612ad9565b5b509250929050565b6000612b4c82611dde565b9150612b5783611dde565b9250828201905080821115612b6f57612b6e612476565b5b92915050565b7f43616e27742073656e64206d6f7265207468616e206d73672e76616c75650000600082015250565b6000612bab601e83612341565b9150612bb682612b75565b602082019050919050565b60006020820190508181036000830152612bda81612b9e565b9050919050565b600081519050919050565b6000612bf782612be1565b612c018185612585565b9350612c118185602086016124e4565b80840191505092915050565b6000612c298284612bec565b915081905092915050565b6000612c3f82611dde565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612c7157612c70612476565b5b600182019050919050565b6000606082019050612c9160008301866122b2565b612c9e60208301856122b2565b612cab6040830184611de8565b949350505050565b7f4661696c656420746f207472616e7366657220746f6b656e0000000000000000600082015250565b6000612ce9601883612341565b9150612cf482612cb3565b602082019050919050565b60006020820190508181036000830152612d1881612cdc565b9050919050565b600082825260208201905092915050565b6000612d3d600083612d1f565b9150612d4882612590565b600082019050919050565b600060a082019050612d6860008301876122b2565b612d7560208301866122b2565b612d826040830185611de8565b612d8f6060830184611de8565b8181036080830152612da081612d30565b905095945050505050565b6000608082019050612dc060008301866122b2565b612dcd60208301856122b2565b612dda6040830184611de8565b8181036060830152612deb81612d30565b9050949350505050565b6000612e0082612be1565b612e0a8185612d1f565b9350612e1a8185602086016124e4565b612e2381611ee6565b840191505092915050565b60006020820190508181036000830152612e488184612df5565b905092915050565b6000612e63612e5e84611f72565b611f57565b905082815260208101848484011115612e7f57612e7e611ee1565b5b612e8a8482856124e4565b509392505050565b600082601f830112612ea757612ea6611edc565b5b8151612eb7848260208601612e50565b91505092915050565b600060208284031215612ed657612ed5611d19565b5b600082015167ffffffffffffffff811115612ef457612ef3611d1e565b5b612f0084828501612e92565b91505092915050565b60006020820190508181036000830152612f23818461250e565b90509291505056fea2646970667358221220c4b0ecdb0a7c50a50dc2ac8890ab2ea3b676a4d554a5c759c923af58c422a66e64736f6c63430008110033
Deployed Bytecode
0x60806040526004361061014b5760003560e01c80635cfdb086116100b6578063894760691161006f578063894760691461041e5780638d157db8146104475780638da5cb5b146104635780639cd6aa4c1461048e578063b20d0bff146104cb578063f2fde38b146104f45761014b565b80635cfdb08614610331578063704802751461035a5780637129607a14610383578063715018a61461039f57806382313032146103b657806383a4c7e1146103f35761014b565b806327e1f7df1161010857806327e1f7df1461024457806330ae06e01461026d5780633ccfd60b1461029657806341dfeca5146102ad578063429b62e5146102c95780635c73f163146103065761014b565b806301ffc9a71461015057806303f613dc1461018d5780630728c7d2146101b85780630f7f630a146101e157806316e491451461020c5780631e897afb14610228575b600080fd5b34801561015c57600080fd5b5061017760048036038101906101729190611d7b565b61051d565b6040516101849190611dc3565b60405180910390f35b34801561019957600080fd5b506101a26105ef565b6040516101af9190611df7565b60405180910390f35b3480156101c457600080fd5b506101df60048036038101906101da9190611e3e565b6105f5565b005b3480156101ed57600080fd5b506101f6610695565b6040516102039190611df7565b60405180910390f35b61022660048036038101906102219190612022565b61069b565b005b610242600480360381019061023d91906120f1565b6107bd565b005b34801561025057600080fd5b5061026b6004803603810190610266919061213e565b6107cb565b005b34801561027957600080fd5b50610294600480360381019061028f919061216b565b61082e565b005b3480156102a257600080fd5b506102ab610883565b005b6102c760048036038101906102c29190612198565b6109bc565b005b3480156102d557600080fd5b506102f060048036038101906102eb919061213e565b610ad3565b6040516102fd9190611dc3565b60405180910390f35b34801561031257600080fd5b5061031b610af3565b6040516103289190611df7565b60405180910390f35b34801561033d57600080fd5b506103586004803603810190610353919061213e565b610af9565b005b34801561036657600080fd5b50610381600480360381019061037c919061213e565b610b5c565b005b61039d6004803603810190610398919061221b565b610bbf565b005b3480156103ab57600080fd5b506103b4610c7c565b005b3480156103c257600080fd5b506103dd60048036038101906103d8919061213e565b610cbf565b6040516103ea9190611dc3565b60405180910390f35b3480156103ff57600080fd5b50610408610cdf565b6040516104159190611df7565b60405180910390f35b34801561042a57600080fd5b506104456004803603810190610440919061213e565b610ce4565b005b610461600480360381019061045c9190612198565b610e6f565b005b34801561046f57600080fd5b50610478610f2a565b60405161048591906122c1565b60405180910390f35b34801561049a57600080fd5b506104b560048036038101906104b09190612301565b610f53565b6040516104c29190611df7565b60405180910390f35b3480156104d757600080fd5b506104f260048036038101906104ed919061213e565b611043565b005b34801561050057600080fd5b5061051b6004803603810190610516919061213e565b61109d565b005b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105e857507fa7d69893000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60025481565b6105fd611120565b60008211610640576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610637906123c4565b60405180910390fd5b60008111610683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161067a90612456565b60405180910390fd5b81600181905550806002819055505050565b60035481565b600080600554116106ac57346106b0565b6005545b90506000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561070e57819050610720565b61071982600061119e565b9050809150505b61072a85826112cf565b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f06961b35a44f36e67b4d43a3b991e1f866c108a1417c6a986d4ba271b32cefe78685868861079f91906124a5565b6040516107ae93929190612547565b60405180910390a45050505050565b6107c78282611380565b5050565b6107d3611120565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610836611120565b60008111610879576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610870906123c4565b60405180910390fd5b8060038190555050565b60011515600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151461090d576040517f3db4b39200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff1647604051610933906125b6565b60006040518083038185875af1925050503d8060008114610970576040519150601f19603f3d011682016040523d82523d6000602084013e610975565b606091505b50509050806109b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109b090612617565b60405180910390fd5b50565b6000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610a1857839050610a2a565b610a2384600161119e565b9050809150505b610a36843330866115eb565b610a418186856116bc565b8273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f06961b35a44f36e67b4d43a3b991e1f866c108a1417c6a986d4ba271b32cefe78585868a610ab591906124a5565b604051610ac493929190612547565b60405180910390a45050505050565b60076020528060005260406000206000915054906101000a900460ff1681565b60015481565b610b01611120565b6001600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610b64611120565b6001600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008060055411610bd05734610bd4565b6005545b90506000610be382600361119e565b509050610bf38686338a8861178a565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f06961b35a44f36e67b4d43a3b991e1f866c108a1417c6a986d4ba271b32cefe7868686604051610c6b93929190612547565b60405180910390a450505050505050565b610c84611120565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb690612683565b60405180910390fd5b60086020528060005260406000206000915054906101000a900460ff1681565b600581565b60011515600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514610d6e576040517f3db4b39200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008190508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610dc991906122c1565b602060405180830381865afa158015610de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0a91906126b8565b6040518363ffffffff1660e01b8152600401610e279291906126e5565b6020604051808303816000875af1158015610e46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6a919061273a565b505050565b60008060055411610e805734610e84565b6005545b90506000610e9382600261119e565b509050610ea285338887611808565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f06961b35a44f36e67b4d43a3b991e1f866c108a1417c6a986d4ba271b32cefe7868686604051610f1a93929190612547565b60405180910390a4505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080610f5e611883565b90506000610f6b8561188d565b9050600060046000866003811115610f8657610f85612767565b5b6003811115610f9857610f97612767565b5b815260200190815260200160002060009054906101000a900460ff169050600280811115610fc957610fc8612767565b5b816002811115610fdc57610fdb612767565b5b03610fec5782935050505061103d565b6000600281111561100057610fff612767565b5b81600281111561101357611012612767565b5b036110235781935050505061103d565b828211156110365781935050505061103d565b8293505050505b92915050565b61104b611120565b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff021916905550565b6110a5611120565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611114576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110b90612808565b60405180910390fd5b61111d816118b1565b50565b611128611975565b73ffffffffffffffffffffffffffffffffffffffff16611146610f2a565b73ffffffffffffffffffffffffffffffffffffffff161461119c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119390612874565b60405180910390fd5b565b60008060006111ab611883565b905060006111b98686610f53565b9050600060028111156111cf576111ce612767565b5b600460008760038111156111e6576111e5612767565b5b60038111156111f8576111f7612767565b5b815260200190815260200160002060009054906101000a900460ff16600281111561122657611225612767565b5b14158015611258575060646005606461123f91906124a5565b8361124a9190612894565b6112549190612905565b8610155b80156112645750818611155b1561127157859350611275565b8093505b838610156112b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112af906129a8565b60405180910390fd5b83866112c491906124a5565b925050509250929050565b60008273ffffffffffffffffffffffffffffffffffffffff16826040516112f5906125b6565b60006040518083038185875af1925050503d8060008114611332576040519150601f19603f3d011682016040523d82523d6000602084013e611337565b606091505b505090508061137b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137290612a14565b60405180910390fd5b505050565b6002600654036113c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bc90612a80565b60405180910390fd5b6000600260068190555060005b838390508110156115dd576000606060008686858181106113f6576113f5612aa0565b5b90506020028101906114089190612ade565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060008060200182015190506114618161197d565b156115485760006114728284611abb565b90508060058190555080876114879190612b41565b9650348711156114cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c390612bc1565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16836040516114f19190612c1d565b600060405180830381855af49150503d806000811461152c576040519150601f19603f3d011682016040523d82523d6000602084013e611531565b606091505b5080955081965050506000600581905550506115b7565b3073ffffffffffffffffffffffffffffffffffffffff168260405161156d9190612c1d565b600060405180830381855af49150503d80600081146115a8576040519150601f19603f3d011682016040523d82523d6000602084013e6115ad565b606091505b5080945081955050505b836115c6576115c583611c72565b5b5050505080806115d590612c34565b9150506113d2565b506001600681905550505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166323b872dd8686896040518463ffffffff1660e01b815260040161162f93929190612c7c565b6020604051808303816000875af115801561164e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611672919061273a565b9050806116b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ab90612cff565b60405180910390fd5b505050505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85876040518363ffffffff1660e01b81526004016116fe9291906126e5565b6020604051808303816000875af115801561171d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611741919061273a565b905080611783576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177a90612cff565b60405180910390fd5b5050505050565b60008190508073ffffffffffffffffffffffffffffffffffffffff1663f242432a858589896040518563ffffffff1660e01b81526004016117ce9493929190612d53565b600060405180830381600087803b1580156117e857600080fd5b505af11580156117fc573d6000803e3d6000fd5b50505050505050505050565b60008190508073ffffffffffffffffffffffffffffffffffffffff1663b88d4fde8585886040518463ffffffff1660e01b815260040161184a93929190612dab565b600060405180830381600087803b15801561186457600080fd5b505af1158015611878573d6000803e3d6000fd5b505050505050505050565b6000600354905090565b6000600254600154836118a09190612894565b6118aa9190612905565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b60006316e4914560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a1657506341dfeca560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611a655750638d157db860e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611ab45750637129607a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000806316e4914560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611b165760448301519050611c68565b6341dfeca560e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611b7557611b6e60006001610f53565b9050611c67565b638d157db860e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611bd457611bcd60006002610f53565b9050611c66565b637129607a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611c3357611c2c60006003610f53565b9050611c65565b6040517f2f4aeaf500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b5b8091505092915050565b604481511015611cb957806040517fd9354485000000000000000000000000000000000000000000000000000000008152600401611cb09190612e2e565b60405180910390fd5b60048101905080806020019051810190611cd39190612ec0565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d069190612f09565b60405180910390fd5b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611d5881611d23565b8114611d6357600080fd5b50565b600081359050611d7581611d4f565b92915050565b600060208284031215611d9157611d90611d19565b5b6000611d9f84828501611d66565b91505092915050565b60008115159050919050565b611dbd81611da8565b82525050565b6000602082019050611dd86000830184611db4565b92915050565b6000819050919050565b611df181611dde565b82525050565b6000602082019050611e0c6000830184611de8565b92915050565b611e1b81611dde565b8114611e2657600080fd5b50565b600081359050611e3881611e12565b92915050565b60008060408385031215611e5557611e54611d19565b5b6000611e6385828601611e29565b9250506020611e7485828601611e29565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611ea982611e7e565b9050919050565b611eb981611e9e565b8114611ec457600080fd5b50565b600081359050611ed681611eb0565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611f2f82611ee6565b810181811067ffffffffffffffff82111715611f4e57611f4d611ef7565b5b80604052505050565b6000611f61611d0f565b9050611f6d8282611f26565b919050565b600067ffffffffffffffff821115611f8d57611f8c611ef7565b5b611f9682611ee6565b9050602081019050919050565b82818337600083830152505050565b6000611fc5611fc084611f72565b611f57565b905082815260208101848484011115611fe157611fe0611ee1565b5b611fec848285611fa3565b509392505050565b600082601f83011261200957612008611edc565b5b8135612019848260208601611fb2565b91505092915050565b60008060006060848603121561203b5761203a611d19565b5b600061204986828701611ec7565b935050602061205a86828701611e29565b925050604084013567ffffffffffffffff81111561207b5761207a611d1e565b5b61208786828701611ff4565b9150509250925092565b600080fd5b600080fd5b60008083601f8401126120b1576120b0611edc565b5b8235905067ffffffffffffffff8111156120ce576120cd612091565b5b6020830191508360208202830111156120ea576120e9612096565b5b9250929050565b6000806020838503121561210857612107611d19565b5b600083013567ffffffffffffffff81111561212657612125611d1e565b5b6121328582860161209b565b92509250509250929050565b60006020828403121561215457612153611d19565b5b600061216284828501611ec7565b91505092915050565b60006020828403121561218157612180611d19565b5b600061218f84828501611e29565b91505092915050565b600080600080608085870312156121b2576121b1611d19565b5b60006121c087828801611ec7565b94505060206121d187828801611e29565b93505060406121e287828801611ec7565b925050606085013567ffffffffffffffff81111561220357612202611d1e565b5b61220f87828801611ff4565b91505092959194509250565b600080600080600060a0868803121561223757612236611d19565b5b600061224588828901611ec7565b955050602061225688828901611e29565b945050604061226788828901611e29565b935050606061227888828901611ec7565b925050608086013567ffffffffffffffff81111561229957612298611d1e565b5b6122a588828901611ff4565b9150509295509295909350565b6122bb81611e9e565b82525050565b60006020820190506122d660008301846122b2565b92915050565b600481106122e957600080fd5b50565b6000813590506122fb816122dc565b92915050565b6000806040838503121561231857612317611d19565b5b600061232685828601611e29565b9250506020612337858286016122ec565b9150509250929050565b600082825260208201905092915050565b7f5061796d656e74206665652068617320746f206265206269676765722074686160008201527f6e20300000000000000000000000000000000000000000000000000000000000602082015250565b60006123ae602383612341565b91506123b982612352565b604082019050919050565b600060208201905081810360008301526123dd816123a1565b9050919050565b7f5061796d656e74206665652064656e6f6d696e61746f722068617320746f206260008201527f6520626967676572207468616e20300000000000000000000000000000000000602082015250565b6000612440602f83612341565b915061244b826123e4565b604082019050919050565b6000602082019050818103600083015261246f81612433565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006124b082611dde565b91506124bb83611dde565b92508282039050818111156124d3576124d2612476565b5b92915050565b600081519050919050565b60005b838110156125025780820151818401526020810190506124e7565b60008484015250505050565b6000612519826124d9565b6125238185612341565b93506125338185602086016124e4565b61253c81611ee6565b840191505092915050565b60006060820190508181036000830152612561818661250e565b90506125706020830185611de8565b61257d6040830184611de8565b949350505050565b600081905092915050565b50565b60006125a0600083612585565b91506125ab82612590565b600082019050919050565b60006125c182612593565b9150819050919050565b7f4661696c656420746f2077697468647261772e00000000000000000000000000600082015250565b6000612601601383612341565b915061260c826125cb565b602082019050919050565b60006020820190508181036000830152612630816125f4565b9050919050565b7f4f7065726174696f6e206e6f7420737570706f72746564000000000000000000600082015250565b600061266d601783612341565b915061267882612637565b602082019050919050565b6000602082019050818103600083015261269c81612660565b9050919050565b6000815190506126b281611e12565b92915050565b6000602082840312156126ce576126cd611d19565b5b60006126dc848285016126a3565b91505092915050565b60006040820190506126fa60008301856122b2565b6127076020830184611de8565b9392505050565b61271781611da8565b811461272257600080fd5b50565b6000815190506127348161270e565b92915050565b6000602082840312156127505761274f611d19565b5b600061275e84828501612725565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006127f2602683612341565b91506127fd82612796565b604082019050919050565b60006020820190508181036000830152612821816127e5565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061285e602083612341565b915061286982612828565b602082019050919050565b6000602082019050818103600083015261288d81612851565b9050919050565b600061289f82611dde565b91506128aa83611dde565b92508282026128b881611dde565b915082820484148315176128cf576128ce612476565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061291082611dde565b915061291b83611dde565b92508261292b5761292a6128d6565b5b828204905092915050565b7f56616c75652073656e7420697320736d616c6c6572207468616e206d696e696d60008201527f616c206665652e00000000000000000000000000000000000000000000000000602082015250565b6000612992602783612341565b915061299d82612936565b604082019050919050565b600060208201905081810360008301526129c181612985565b9050919050565b7f4661696c656420746f2073656e64000000000000000000000000000000000000600082015250565b60006129fe600e83612341565b9150612a09826129c8565b602082019050919050565b60006020820190508181036000830152612a2d816129f1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a6a601f83612341565b9150612a7582612a34565b602082019050919050565b60006020820190508181036000830152612a9981612a5d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112612afb57612afa612acf565b5b80840192508235915067ffffffffffffffff821115612b1d57612b1c612ad4565b5b602083019250600182023603831315612b3957612b38612ad9565b5b509250929050565b6000612b4c82611dde565b9150612b5783611dde565b9250828201905080821115612b6f57612b6e612476565b5b92915050565b7f43616e27742073656e64206d6f7265207468616e206d73672e76616c75650000600082015250565b6000612bab601e83612341565b9150612bb682612b75565b602082019050919050565b60006020820190508181036000830152612bda81612b9e565b9050919050565b600081519050919050565b6000612bf782612be1565b612c018185612585565b9350612c118185602086016124e4565b80840191505092915050565b6000612c298284612bec565b915081905092915050565b6000612c3f82611dde565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612c7157612c70612476565b5b600182019050919050565b6000606082019050612c9160008301866122b2565b612c9e60208301856122b2565b612cab6040830184611de8565b949350505050565b7f4661696c656420746f207472616e7366657220746f6b656e0000000000000000600082015250565b6000612ce9601883612341565b9150612cf482612cb3565b602082019050919050565b60006020820190508181036000830152612d1881612cdc565b9050919050565b600082825260208201905092915050565b6000612d3d600083612d1f565b9150612d4882612590565b600082019050919050565b600060a082019050612d6860008301876122b2565b612d7560208301866122b2565b612d826040830185611de8565b612d8f6060830184611de8565b8181036080830152612da081612d30565b905095945050505050565b6000608082019050612dc060008301866122b2565b612dcd60208301856122b2565b612dda6040830184611de8565b8181036060830152612deb81612d30565b9050949350505050565b6000612e0082612be1565b612e0a8185612d1f565b9350612e1a8185602086016124e4565b612e2381611ee6565b840191505092915050565b60006020820190508181036000830152612e488184612df5565b905092915050565b6000612e63612e5e84611f72565b611f57565b905082815260208101848484011115612e7f57612e7e611ee1565b5b612e8a8482856124e4565b509392505050565b600082601f830112612ea757612ea6611edc565b5b8151612eb7848260208601612e50565b91505092915050565b600060208284031215612ed657612ed5611d19565b5b600082015167ffffffffffffffff811115612ef457612ef3611d1e565b5b612f0084828501612e92565b91505092915050565b60006020820190508181036000830152612f23818461250e565b90509291505056fea2646970667358221220c4b0ecdb0a7c50a50dc2ac8890ab2ea3b676a4d554a5c759c923af58c422a66e64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
MANTLE | 72.74% | $0.704064 | 147.9926 | $104.2 | |
BASE | 14.73% | $0.999912 | 21.104 | $21.1 | |
BASE | 4.27% | $1,789.66 | 0.00341544 | $6.11 | |
BASE | 3.69% | $2.78 | 1.9003 | $5.28 | |
BASE | 3.08% | $0.003166 | 1,395.15 | $4.42 | |
BASE | 0.92% | $0.000002 | 740,000 | $1.32 | |
BASE | 0.33% | $0.032635 | 14.5444 | $0.4746 | |
BASE | 0.17% | $0.003219 | 75.6565 | $0.2435 | |
SCROLL | 0.07% | $1,791.97 | 0.00005417 | $0.097067 |
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.