Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
15279331 | 851 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Minimal Proxy Contract for 0x4a982a67312a34ef2a0047e730b58f1de05e92b1
Contract Name:
ImmutablesPageRoyaltyManager
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: UNLICENSED // All Rights Reserved /* $$$$$$\ $$\ $$\ $$\ $$\ $$\ $$\ $$$$$$$$\ $$$$$$\ $$$$$$$\ $$\ $$$$$$$$\ $$$$$$\ \_$$ _|$$$\ $$$ |$$$\ $$$ |$$ | $$ |\__$$ __|$$ __$$\ $$ __$$\ $$ | $$ _____|$$ __$$\ $$ | $$$$\ $$$$ |$$$$\ $$$$ |$$ | $$ | $$ | $$ / $$ |$$ | $$ |$$ | $$ | $$ / \__| $$ | $$\$$\$$ $$ |$$\$$\$$ $$ |$$ | $$ | $$ | $$$$$$$$ |$$$$$$$\ |$$ | $$$$$\ \$$$$$$\ $$ | $$ \$$$ $$ |$$ \$$$ $$ |$$ | $$ | $$ | $$ __$$ |$$ __$$\ $$ | $$ __| \____$$\ $$ | $$ |\$ /$$ |$$ |\$ /$$ |$$ | $$ | $$ | $$ | $$ |$$ | $$ |$$ | $$ | $$\ $$ | $$$$$$\ $$ | \_/ $$ |$$ | \_/ $$ |\$$$$$$ | $$ | $$ | $$ |$$$$$$$ |$$$$$$$$\ $$$$$$$$\ \$$$$$$ | \______|\__| \__|\__| \__| \______/ \__| \__| \__|\_______/ \________|\________| \______/ $$$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\ $$\ $$$$$$$$\ $$\ $$\ $$ __$$\ $$ __$$\\$$\ $$ |$$ __$$\ $$ | \__$$ __|\$$\ $$ | $$ | $$ |$$ / $$ |\$$\ $$ / $$ / $$ |$$ | $$ | \$$\ $$ / $$$$$$$ |$$ | $$ | \$$$$ / $$$$$$$$ |$$ | $$ | \$$$$ / $$ __$$< $$ | $$ | \$$ / $$ __$$ |$$ | $$ | \$$ / $$ | $$ |$$ | $$ | $$ | $$ | $$ |$$ | $$ | $$ | $$ | $$ | $$$$$$ | $$ | $$ | $$ |$$$$$$$$\ $$ | $$ | \__| \__| \______/ \__| \__| \__|\________|\__| \__| $$\ $$\ $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$\ $$$$$$$$\ $$$$$$$\ $$$\ $$$ |$$ __$$\ $$$\ $$ |$$ __$$\ $$ __$$\ $$ _____|$$ __$$\ $$$$\ $$$$ |$$ / $$ |$$$$\ $$ |$$ / $$ |$$ / \__|$$ | $$ | $$ | $$\$$\$$ $$ |$$$$$$$$ |$$ $$\$$ |$$$$$$$$ |$$ |$$$$\ $$$$$\ $$$$$$$ | $$ \$$$ $$ |$$ __$$ |$$ \$$$$ |$$ __$$ |$$ |\_$$ |$$ __| $$ __$$< $$ |\$ /$$ |$$ | $$ |$$ |\$$$ |$$ | $$ |$$ | $$ |$$ | $$ | $$ | $$ | \_/ $$ |$$ | $$ |$$ | \$$ |$$ | $$ |\$$$$$$ |$$$$$$$$\ $$ | $$ | \__| \__|\__| \__|\__| \__|\__| \__| \______/ \________|\__| \__| */ pragma solidity ^0.8.0; /** * @royaltyRecipient Gutenblock.eth * @title ImmutablesPageRoyaltyManager * @dev This contract allows to split Ether royalty payments between the * Immutables.co contract and an Immutables.co page royaltyRecipient. * * `ImmutablesPageRoyaltyManager` follows a _pull payment_ model. This means that payments * are not automatically forwarded to the accounts but kept in this contract, * and the actual transfer is triggered as a separate step by calling the * {release} function. * * The contract is written to serve as an implementation for minimal proxy clones. */ import "./Context.sol"; import "./Address.sol"; import "./Initializable.sol"; import "./ReentrancyGuard.sol"; contract ImmutablesPageRoyaltyManager is Context, Initializable, ReentrancyGuard { using Address for address payable; /// @dev Reentrancy protection. //bool locked = false; /// @dev The address of the ImmutablesPage contract. address public immutablesPageContract; /// @dev The tokenId of the associated ImmutablesPage. uint256 public immutablesPageTokenId; /// @dev The name of the associated ImmutablesPage. string public immutablesPage; /// @dev The address of the royaltyRecipient. address public royaltyRecipient; /// @dev The address of the additionalPayee set by the royaltyRecipient. address public additionalPayee; /// @dev The royaltyRecipient's percentage of the total expressed as 1/1000ths. /// The royaltyRecipient can allot up to all of this to an additionalPayee. uint16 public royaltyRecipientPercent; /// @dev The royaltyRecipient's percentage, after additional payee, /// of the total expressed in basis points. uint16 public royaltyRecipientPercentMinusAdditionalPayeePercent; /// @dev The royaltyRecipient's additional payee percentae of the total /// @dev expressed in basis points. Valid from 0 to royaltyRecipientPercent. uint16 public additionalPayeePercent; /// EVENTS event PayeeAdded(address account, uint256 percent); event PayeeRemoved(address account, uint256 percent); event PaymentReleased(address to, uint256 amount); event PaymentReceived(address from, uint256 amount); /** * @dev Creates an uninitialized instance of `ImmutablesPageRoyaltyManager`. */ constructor() { } /** * @dev Initialized an instance of `ImmutablesPageRoyaltyManager` */ function initialize(address _immutablesPageContract, uint256 _immutablesPageTokenId, string calldata _immutablesPage, address _royaltyRecipient, uint16 _royaltyRecipientPercent, address _additionalPayee, uint16 _additionalPayeePercent ) public initializer() { immutablesPageContract = _immutablesPageContract; immutablesPageTokenId = _immutablesPageTokenId; immutablesPage = _immutablesPage; royaltyRecipient = _royaltyRecipient; royaltyRecipientPercent = _royaltyRecipientPercent; additionalPayee = _additionalPayee; additionalPayeePercent = _additionalPayeePercent; royaltyRecipientPercentMinusAdditionalPayeePercent = _royaltyRecipientPercent - _additionalPayeePercent; emit PayeeAdded(immutablesPageContract, 10000 - royaltyRecipientPercent); emit PayeeAdded(royaltyRecipient, royaltyRecipientPercentMinusAdditionalPayeePercent); if(additionalPayee != address(0)) { emit PayeeAdded(additionalPayee, additionalPayeePercent); } } /** * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the * reliability of the events, and not the actual splitting of Ether. * * To learn more about this see the Solidity documentation for * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback * functions]. */ receive() external payable virtual { emit PaymentReceived(_msgSender(), msg.value); } /** @dev Allows the current royalty recipient to set/update the royalty recipieint address. * @param _newRoyaltyRecipient The new royalty recipieint. */ function royaltyRecipientUpdateAddress(address _newRoyaltyRecipient) public { // only the parent contract and the royaltyRecipient can call this function. // the parent contract only calls this function at the request of the royaltyRecipient. require(_msgSender() == immutablesPageContract || _msgSender() == royaltyRecipient, "auth"); // update the royaltyRecipient address emit PayeeRemoved(royaltyRecipient, royaltyRecipientPercentMinusAdditionalPayeePercent); royaltyRecipient = _newRoyaltyRecipient; emit PayeeAdded(royaltyRecipient, royaltyRecipientPercentMinusAdditionalPayeePercent); } /** @dev Allows the current royalty recipient to update additional payee information. * @param _newAdditionalPayee The new additional payee. * @param _newPercent A new additional payee percentage in basis points. */ /** @dev Allows the royaltyRecipient to update additional payee info. * @param _newAdditionalPayee the additional payee address. * @param _newPercent the basis point (1/10,000th) share for the _additionalPayee up to artistPercent (e.g., 5000 = 50.0%). */ function royaltyRecipientUpdateAdditionalPayeeInfo(address _newAdditionalPayee, uint16 _newPercent) public { // only the parent contract and the royaltyRecipient can call this function. // the parent contract only calls this function at the request of the royaltyRecipient. require(_msgSender() == immutablesPageContract || _msgSender() == royaltyRecipient, "auth"); // the maximum amount the royaltyRecipient can give to an additional payee is // the current royaltyRecipientPercent plus the current additionalPayeePercent. require(_newPercent <= royaltyRecipientPercent, "percent too big"); // Before changing the additional payee information, // payout everyone as indicated when prior payments were made. release(); // Change the additional payee and relevant percentages. emit PayeeRemoved(royaltyRecipient, royaltyRecipientPercentMinusAdditionalPayeePercent); if(additionalPayee != address(0)) { emit PayeeRemoved(additionalPayee, additionalPayeePercent); } additionalPayee = _newAdditionalPayee; additionalPayeePercent = _newPercent; royaltyRecipientPercentMinusAdditionalPayeePercent = royaltyRecipientPercent - _newPercent; emit PayeeAdded(royaltyRecipient, royaltyRecipientPercentMinusAdditionalPayeePercent); if(additionalPayee != address(0)) { emit PayeeAdded(additionalPayee, additionalPayeePercent); } } /** * @dev Triggers payout of all royalties. */ function release() public virtual nonReentrant() { // checks // effects uint256 _startingBalance = address(this).balance; uint256 _royaltyRecipientAmount = _startingBalance * royaltyRecipientPercentMinusAdditionalPayeePercent / 10000; uint256 _additionalPayeeAmount = _startingBalance * additionalPayeePercent / 10000; uint256 _contractAmount = _startingBalance - _royaltyRecipientAmount - _additionalPayeeAmount; // interactions if(_startingBalance > 0) { payable(immutablesPageContract).sendValue(_contractAmount); emit PaymentReleased(immutablesPageContract, _contractAmount); payable(royaltyRecipient).sendValue(_royaltyRecipientAmount); emit PaymentReleased(royaltyRecipient, _royaltyRecipientAmount); } if(_startingBalance > 0 && additionalPayee != address(0) && additionalPayeePercent > 0) { payable(additionalPayee).sendValue(_additionalPayeeAmount); emit PaymentReleased(additionalPayee, _additionalPayeeAmount); } } }
File 2 of 5: Address.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
File 3 of 5: Context.sol
// SPDX-License-Identifier: MIT 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; } }
File 4 of 5: Initializable.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
File 5 of 5: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"percent","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"percent","type":"uint256"}],"name":"PayeeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"inputs":[],"name":"additionalPayee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"additionalPayeePercent","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"immutablesPage","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"immutablesPageContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"immutablesPageTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_immutablesPageContract","type":"address"},{"internalType":"uint256","name":"_immutablesPageTokenId","type":"uint256"},{"internalType":"string","name":"_immutablesPage","type":"string"},{"internalType":"address","name":"_royaltyRecipient","type":"address"},{"internalType":"uint16","name":"_royaltyRecipientPercent","type":"uint16"},{"internalType":"address","name":"_additionalPayee","type":"address"},{"internalType":"uint16","name":"_additionalPayeePercent","type":"uint16"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royaltyRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyRecipientPercent","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyRecipientPercentMinusAdditionalPayeePercent","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAdditionalPayee","type":"address"},{"internalType":"uint16","name":"_newPercent","type":"uint16"}],"name":"royaltyRecipientUpdateAdditionalPayeeInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newRoyaltyRecipient","type":"address"}],"name":"royaltyRecipientUpdateAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 29 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.