Transaction Hash:
Block:
16538545 at Feb-02-2023 03:49:47 AM +UTC
Transaction Fee:
0.000461925701362925 ETH
$1.20
Gas Used:
24,691 Gas / 18.708262175 Gwei
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x690B9A9E...Db4FaC990
Miner
| (builder0x69) | 2.057064002358881729 Eth | 2.057088693358881729 Eth | 0.000024691 | |
0xb2b0153A...940930b80 |
13.128823428008552417 Eth
Nonce: 249
|
13.128361502307189492 Eth
Nonce: 250
| 0.000461925701362925 |
Execution Trace
NFTBridgeMinter.c0d2d6cb( )
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; contract Managed { mapping(address => bool) public managers; modifier onlyManagers() { require(managers[msg.sender] == true, "Caller is not manager"); _; } constructor() { managers[msg.sender] = true; } function setManager(address _wallet, bool _manager) public onlyManagers { require(_wallet != msg.sender, "Not allowed"); managers[_wallet] = _manager; } } interface INFTBridgeLog { function outgoing(address _wallet, uint256 _assetId, uint256 _chainID, uint256 _bridgeIndex) external; function incoming(address _wallet, uint256 _assetId, uint256 _chainID, uint256 _logIndex, bytes32 txHash, bool _minted) external; } interface INFT3D { function safeTransferFrom(address from, address to, uint256 tokenId) external; function totalSupply() external view returns (uint256); function mint(address to, uint32 _assetType, uint256 _value, uint32 _customDetails) external returns (bool success); } interface IPC3DUpgrader { function getTokenDetails(uint256 index) external view returns (uint32 aType, uint32 customDetails, uint32 lastTx, uint32 lastPayment, uint256 initialvalue, uint32 upgrades, uint32 gDetails, bool leased); function setGameDetails(uint256 index, uint32 _details) external; function setUpgrades(uint256 index, uint32 _upgrades) external; } library ECDSA { function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { bytes32 r; bytes32 s; uint8 v; if (signature.length == 65) { // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } } else if (signature.length == 64) { // solhint-disable-next-line no-inline-assembly assembly { let vs := mload(add(signature, 0x40)) r := mload(add(signature, 0x20)) s := and( vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ) v := add(shr(255, vs), 27) } } else { revert("ECDSA: invalid signature length"); } return recover(hash, v, r, s); } function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value"); require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value"); // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); require(signer != address(0), "ECDSA: invalid signature"); return signer; } function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } contract NFTBridgeMinter is Managed { INFTBridgeLog logger; INFT3D NFTContract; IPC3DUpgrader upgradeContract; uint256 public depositIndex; address public NFTVault; address signer; uint256 chainID; bool public paused; constructor() { NFTContract = INFT3D(0xB20217bf3d89667Fa15907971866acD6CcD570C8); upgradeContract = IPC3DUpgrader(0x2a34c7942C92d2b2f43807225C36fb6763dC0b60); logger = INFTBridgeLog(0x2Ec9BA7B80b1aD442390B4fDf735a2BBA061E803); NFTVault = 0xf7A9F6001ff8b499149569C54852226d719f2D76; chainID = 1; signer = 0xa4C03a9B4f1c67aC645A990DDB7B8A27D4D9e7af; managers[0x00d6E1038564047244Ad37080E2d695924F8515B] = true; } function verifyTXCall(bytes32 _taskHash, bytes memory _sig) public view returns (bool valid) { address mSigner = ECDSA.recover(ECDSA.toEthSignedMessageHash(_taskHash), _sig); if (mSigner == signer) { return true; } else { return false; } } function withdrawclone(address _wallet, uint256 _cloneId, uint32 _upgrades, uint32 _gameDetails, uint256 _chainFrom, uint256 _chainTo, uint256 _logIndex, bytes memory _sig) public { require(!paused, "Contract is paused"); require(_chainTo == chainID, "Invalid chain"); bytes32 txHash = keccak256(abi.encode(_wallet, _cloneId, _upgrades, _gameDetails, _chainFrom, _chainTo, _logIndex)); bool txv = verifyTXCall(txHash, _sig); require (txv == true, "Invalid signature"); logger.incoming(_wallet, _cloneId, _chainFrom, _logIndex, txHash, false); updateAndTransfer(_wallet, _cloneId, _upgrades, _gameDetails); } function updateAndTransfer(address _wallet, uint256 _cloneId, uint32 _upgrades, uint32 _gameDetails) private { upgradeContract.setUpgrades(_cloneId, _upgrades); upgradeContract.setGameDetails(_cloneId, _gameDetails); NFTContract.safeTransferFrom(NFTVault, _wallet, _cloneId); } function withdraw(address _wallet, uint32 _assetType, uint256 _value, uint32 _customDetails, uint32 _upgrades, uint32 _gameDetails, uint256 _chainFrom, uint256 _chainTo, uint256 _logIndex, bytes memory _sig) public { require(!paused, "Contract is paused"); require(_chainTo == chainID, "Invalid chain"); bytes32 txHash = keccak256(abi.encode(_wallet, _assetType, _value, _customDetails, _upgrades, _gameDetails, _chainFrom, _chainTo, _logIndex)); require (verifyTXCall(txHash, _sig) == true, "Invalid signature"); uint256 nIndex = NFTContract.totalSupply(); upgradeContract.setUpgrades(nIndex, _upgrades); upgradeContract.setGameDetails(nIndex, _gameDetails); logger.incoming(_wallet, nIndex, _chainFrom, _logIndex, txHash, true); require(NFTContract.mint(_wallet, _assetType, _value, _customDetails), "Mint fail"); } function setLogger (address _logger) public onlyManagers { logger = INFTBridgeLog(_logger); } function setSigner (address _signer) public onlyManagers { signer = _signer; } function setNFTVault (address _vault) public onlyManagers { NFTVault = _vault; } function pauseContract(bool _paused) public onlyManagers { paused = _paused; } }