MATIC Price: $1.03 (-2.09%)
Gas: 147 GWei
 

Overview

MATIC Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 MATIC

MATIC Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
0x60806040417352962023-04-20 5:12:04313 days 19 hrs ago1681967524IN
 Create: Mapper
0 MATIC0.06171543210

Parent Txn Hash Block From To Value
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Mapper

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 5 : Mapper.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.13;

import "../interfaces/INFT.sol";
import "../libraries/MapperStorage.sol";
import "../libraries/nodes/AftermarketDeviceStorage.sol";

/// @title Mapper
/// @notice Contract to map relationships between nodes and other contracts
contract Mapper {
    event BeneficiarySet(
        address indexed idProxyAddress,
        uint256 indexed nodeId,
        address indexed beneficiary
    );

    /// @notice Sets the beneficiary associated with the aftermarket device
    /// @dev Only the nodeId owner can set a beneficiary
    /// @dev To clear the beneficiary, users can pass the zero address
    /// @param nodeId The node Id to be associated with the beneficiary
    /// @param beneficiary The address to be a beneficiary
    function setAftermarketDeviceBeneficiary(
        uint256 nodeId,
        address beneficiary
    ) external {
        address adProxyAddress = AftermarketDeviceStorage
            .getStorage()
            .idProxyAddress;
        address nodeOwner = INFT(adProxyAddress).ownerOf(nodeId);

        require(
            nodeOwner == msg.sender || adProxyAddress == msg.sender,
            "Only owner or proxy"
        );
        require(nodeOwner != beneficiary, "Beneficiary cannot be the owner");

        MapperStorage.getStorage().beneficiaries[adProxyAddress][
            nodeId
        ] = beneficiary;

        emit BeneficiarySet(adProxyAddress, nodeId, beneficiary);
    }

    /// @notice Gets the link between two nodes
    /// @param idProxyAddress The address of the NFT proxy
    /// @param sourceNode The node Id to be queried
    function getLink(address idProxyAddress, uint256 sourceNode)
        external
        view
        returns (uint256 targetNode)
    {
        targetNode = MapperStorage.getStorage().links[idProxyAddress][
            sourceNode
        ];
    }

    /// @notice Gets the beneficiary associated with the pair idProxy/nodeId.
    /// @notice If the beneficiary is not explicitly set, it defaults to the owner
    /// @param idProxyAddress The address of the NFT proxy
    /// @param nodeId The node Id to be queried
    function getBeneficiary(address idProxyAddress, uint256 nodeId)
        external
        view
        returns (address beneficiary)
    {
        beneficiary = MapperStorage.getStorage().beneficiaries[idProxyAddress][
            nodeId
        ];

        if (beneficiary == address(0)) {
            beneficiary = INFT(idProxyAddress).ownerOf(nodeId);
        }
    }
}

File 2 of 5 : INFT.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.13;

/// @title INFT
/// @notice Interface of a generic NFT
interface INFT {
    function safeMint(address to) external returns (uint256);

    function safeTransferByRegistry(
        address from,
        address to,
        uint256 tokenId
    ) external;

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    function setApprovalForAll(address operator, bool _approved) external;

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    function ownerOf(uint256 tokenId) external view returns (address owner);

    function exists(uint256 tokenId) external view returns (bool);

    function isApprovedForAll(address owner, address operator)
        external
        view
        returns (bool);
}

File 3 of 5 : MapperStorage.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.13;

/// @title MapperStorage
/// @notice Storage of the Mapper contract
library MapperStorage {
    bytes32 internal constant MAPPER_STORAGE_SLOT =
        keccak256("DIMORegistry.mapper.storage");

    struct Storage {
        // Links between Vehicles and ADs
        // idProxyAddress -> vehicleId/adId -> adId/vehicleId
        mapping(address => mapping(uint256 => uint256)) links;
        // Stores beneficiary addresses for a given nodeId of an idProxy
        // idProxyAddress -> nodeId -> beneficiary
        mapping(address => mapping(uint256 => address)) beneficiaries;
    }

    /* solhint-disable no-inline-assembly */
    function getStorage() internal pure returns (Storage storage s) {
        bytes32 slot = MAPPER_STORAGE_SLOT;
        assembly {
            s.slot := slot
        }
    }
    /* solhint-enable no-inline-assembly */
}

File 4 of 5 : AftermarketDeviceStorage.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.13;

import "../AttributeSet.sol";

/// @title AftermarketDeviceStorage
/// @notice Storage of the AftermarketDevice contract
library AftermarketDeviceStorage {
    using AttributeSet for AttributeSet.Set;

    bytes32 private constant AFTERMARKET_DEVICE_STORAGE_SLOT =
        keccak256("DIMORegistry.aftermarketDevice.storage");

    struct Storage {
        address idProxyAddress;
        // Allowed node attribute
        AttributeSet.Set whitelistedAttributes;
        // AD Id => already claimed or not
        mapping(uint256 => bool) deviceClaimed;
        // AD address => AD Id
        mapping(address => uint256) deviceAddressToNodeId;
        // AD Id => AD address
        mapping(uint256 => address) nodeIdToDeviceAddress;
    }

    /* solhint-disable no-inline-assembly */
    function getStorage() internal pure returns (Storage storage s) {
        bytes32 slot = AFTERMARKET_DEVICE_STORAGE_SLOT;
        assembly {
            s.slot := slot
        }
    }
    /* solhint-enable no-inline-assembly */
}

File 5 of 5 : AttributeSet.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.13;

/// @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)

library AttributeSet {
    struct Set {
        string[] _values;
        mapping(string => uint256) _indexes;
    }

    function add(Set storage set, string calldata key) internal returns (bool) {
        if (!exists(set, key)) {
            set._values.push(key);
            set._indexes[key] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    function remove(Set storage set, string calldata key)
        internal
        returns (bool)
    {
        uint256 valueIndex = set._indexes[key];

        if (valueIndex != 0) {
            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                string memory lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[key];

            return true;
        } else {
            return false;
        }
    }

    function count(Set storage set) internal view returns (uint256) {
        return (set._values.length);
    }

    function exists(Set storage set, string calldata key)
        internal
        view
        returns (bool)
    {
        return set._indexes[key] != 0;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"idProxyAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"nodeId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"BeneficiarySet","type":"event"},{"inputs":[{"internalType":"address","name":"idProxyAddress","type":"address"},{"internalType":"uint256","name":"nodeId","type":"uint256"}],"name":"getBeneficiary","outputs":[{"internalType":"address","name":"beneficiary","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"idProxyAddress","type":"address"},{"internalType":"uint256","name":"sourceNode","type":"uint256"}],"name":"getLink","outputs":[{"internalType":"uint256","name":"targetNode","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nodeId","type":"uint256"},{"internalType":"address","name":"beneficiary","type":"address"}],"name":"setAftermarketDeviceBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b5061045a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630a6cef4614610046578063112e62a214610076578063bebc0bfc146100d9575b600080fd5b6100596100543660046103a4565b6100ee565b6040516001600160a01b0390911681526020015b60405180910390f35b6100cb6100843660046103a4565b6001600160a01b039190911660009081527f8de0072239d14d1dc0b1663f3a79da9fe256183709b64b1f3e5b0b12a5f7fc2b60209081526040808320938352929052205490565b60405190815260200161006d565b6100ec6100e73660046103d0565b6101aa565b005b6001600160a01b0382811660009081527f8de0072239d14d1dc0b1663f3a79da9fe256183709b64b1f3e5b0b12a5f7fc2c6020908152604080832085845290915290205416806101a4576040516331a9108f60e11b8152600481018390526001600160a01b03841690636352211e90602401602060405180830381865afa15801561017d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a19190610400565b90505b92915050565b60007fbd2b62274efd52466275a1bdb9d5c24eee154f92a975bae1a3aa799d69d845e1546040516331a9108f60e11b8152600481018590526001600160a01b0390911691506000908290636352211e90602401602060405180830381865afa15801561021a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023e9190610400565b90506001600160a01b03811633148061025f57506001600160a01b03821633145b6102a65760405162461bcd60e51b81526020600482015260136024820152724f6e6c79206f776e6572206f722070726f787960681b60448201526064015b60405180910390fd5b826001600160a01b0316816001600160a01b0316036103075760405162461bcd60e51b815260206004820152601f60248201527f42656e65666963696172792063616e6e6f7420626520746865206f776e657200604482015260640161029d565b6001600160a01b0382811660008181527f8de0072239d14d1dc0b1663f3a79da9fe256183709b64b1f3e5b0b12a5f7fc2c6020908152604080832089845290915280822080546001600160a01b0319169488169485179055518792917ff6f6de47a057b68d993d1ca4c1b8a95e51b10d7efbf516bc3c591eb6c4f209ee91a450505050565b6001600160a01b03811681146103a157600080fd5b50565b600080604083850312156103b757600080fd5b82356103c28161038c565b946020939093013593505050565b600080604083850312156103e357600080fd5b8235915060208301356103f58161038c565b809150509250929050565b60006020828403121561041257600080fd5b815161041d8161038c565b939250505056fea2646970667358221220a8c9d80b85dea428a697436757926f4422990c9be4eed38ab60bc0f6230e0fe364736f6c634300080d0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100415760003560e01c80630a6cef4614610046578063112e62a214610076578063bebc0bfc146100d9575b600080fd5b6100596100543660046103a4565b6100ee565b6040516001600160a01b0390911681526020015b60405180910390f35b6100cb6100843660046103a4565b6001600160a01b039190911660009081527f8de0072239d14d1dc0b1663f3a79da9fe256183709b64b1f3e5b0b12a5f7fc2b60209081526040808320938352929052205490565b60405190815260200161006d565b6100ec6100e73660046103d0565b6101aa565b005b6001600160a01b0382811660009081527f8de0072239d14d1dc0b1663f3a79da9fe256183709b64b1f3e5b0b12a5f7fc2c6020908152604080832085845290915290205416806101a4576040516331a9108f60e11b8152600481018390526001600160a01b03841690636352211e90602401602060405180830381865afa15801561017d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a19190610400565b90505b92915050565b60007fbd2b62274efd52466275a1bdb9d5c24eee154f92a975bae1a3aa799d69d845e1546040516331a9108f60e11b8152600481018590526001600160a01b0390911691506000908290636352211e90602401602060405180830381865afa15801561021a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023e9190610400565b90506001600160a01b03811633148061025f57506001600160a01b03821633145b6102a65760405162461bcd60e51b81526020600482015260136024820152724f6e6c79206f776e6572206f722070726f787960681b60448201526064015b60405180910390fd5b826001600160a01b0316816001600160a01b0316036103075760405162461bcd60e51b815260206004820152601f60248201527f42656e65666963696172792063616e6e6f7420626520746865206f776e657200604482015260640161029d565b6001600160a01b0382811660008181527f8de0072239d14d1dc0b1663f3a79da9fe256183709b64b1f3e5b0b12a5f7fc2c6020908152604080832089845290915280822080546001600160a01b0319169488169485179055518792917ff6f6de47a057b68d993d1ca4c1b8a95e51b10d7efbf516bc3c591eb6c4f209ee91a450505050565b6001600160a01b03811681146103a157600080fd5b50565b600080604083850312156103b757600080fd5b82356103c28161038c565b946020939093013593505050565b600080604083850312156103e357600080fd5b8235915060208301356103f58161038c565b809150509250929050565b60006020828403121561041257600080fd5b815161041d8161038c565b939250505056fea2646970667358221220a8c9d80b85dea428a697436757926f4422990c9be4eed38ab60bc0f6230e0fe364736f6c634300080d0033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.