AdilScan
Blocks
Blocks
Uncles
Forked Blocks (Reorgs)
Transactions
Validated
Pending
Cancel transaction
Tokens
All
ADIL Addresses
APIs
GraphQL
RPC
Eth RPC
Apps
Faucet Testnet
Adil chain
Mainnets
Testnets
Other Networks
Validators
Validators
Punished Validators
Proposal
/
Search
/
Search
Connection Lost
New Vyper Smart Contract Verification
Contract Address
The 0x address supplied on contract creation.
Contract Name
Must match the name specified in the code.
Compiler
latest
v0.4.3rc1
v0.4.2rc1
v0.4.1rc3
v0.4.1rc2
v0.4.1rc1
v0.4.1b4
v0.4.1b3
v0.4.1b2
v0.4.1b1
v0.4.0rc6
v0.4.0rc5
v0.4.0rc4
v0.4.0rc3
v0.4.0rc2
v0.4.0rc1
v0.4.0b6
v0.4.0b5
v0.4.0b4
v0.4.0b3
v0.4.0b2
v0.4.0b1
v0.3.10rc5
v0.3.10rc4
v0.3.10rc3
v0.3.10rc2
v0.3.10
v0.4.3
v0.4.2
v0.4.1
v0.4.0
Enter the Vyper Contract Code
// SPDX-License-Identifier: MIT pragma solidity ^0.8.2; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "./abstracts/OwnerOperator.sol"; import "./interfaces/IHorseItemNFT.sol"; import "./interfaces/ITicket.sol"; import "./libraries/StringLibrary.sol"; import "./libraries/BytesLibrary.sol"; contract SwapTicket is Initializable, OwnerOperator, ERC721HolderUpgradeable { using StringLibrary for string; using BytesLibrary for bytes32; using EnumerableSet for EnumerableSet.UintSet; struct SwapData { uint256 uniqueId; uint8 tokenId; uint256 tokenAmount; uint256 horseItemAmount; string userId; uint256 timestamp; uint8 v; bytes32 r; bytes32 s; } struct SwappedItems { address horseItemAddress; uint256[] horseItemIds; } ITicket private ticket; IHorseItemNFT private horseItemNFT; uint8 public horseForTicket; uint256 public timeExpiredSignature; mapping(uint8 => EnumerableSet.UintSet) private horseItems; mapping(uint256 => SwappedItems) private swappedItemIds; address public signerAddress; event HorseItemSet(uint8 indexed ticketType, uint256 indexed horseId); event HorseItemRemoved(uint8 indexed ticketType, uint256 indexed horseId); event HorseItemsSwapped( uint256 uniqueIds, address ticketSwapped, uint8 ticketIdSwapped, uint256 ticketBurnedAmount, address indexed to, uint256[] horseItemIds, string userId ); function init( ITicket _ticket, IHorseItemNFT _horseItemNFT ) public initializer { require(address(_ticket) != address(0), "Zero Ticket address"); require( address(_horseItemNFT) != address(0), "Zero HorseItemNFT address" ); super.initialize(); __ERC721Holder_init(); ticket = _ticket; horseItemNFT = _horseItemNFT; } function removeSwappedItemIds( uint256[] memory _ids ) external operatorOrOwner { for (uint256 i = 0; i < _ids.length; i++) { delete swappedItemIds[_ids[i]]; } } function setSignerAddress(address _signerAddress) external operatorOrOwner { require(_signerAddress != address(0), "Zero signer address"); signerAddress = _signerAddress; } function setTimeExpiredSignature( uint256 _timeExpiredSignature ) external operatorOrOwner { timeExpiredSignature = _timeExpiredSignature; } function setHorseForTicket(uint8 _horseForTicket) external operatorOrOwner { horseForTicket = _horseForTicket; } function setHorseItems( uint8 _ticketId, uint256[] calldata _ids ) external operatorOrOwner { for (uint256 i = 0; i < _ids.length; i++) { setHorseItem(_ticketId, _ids[i]); } } function setHorseItem(uint8 _ticketId, uint256 _id) internal { require( horseItemNFT.ownerOf(_id) == address(this), "SwapTicket: Horse not owned by contract" ); horseItems[_ticketId].add(_id); emit HorseItemSet(_ticketId, _id); } function setTicket(ITicket _ticket) external operatorOrOwner { require(address(_ticket) != address(0), "Zero Ticket address"); ticket = _ticket; } function setHorseItemNFT( IHorseItemNFT _horseItemNFT ) external operatorOrOwner { require(address(_horseItemNFT) != address(0), "Zero HorseNFT address"); horseItemNFT = _horseItemNFT; } function removeHorseItems( uint8 _ticketId, uint256[] calldata _ids ) external operatorOrOwner { for (uint256 i = 0; i < _ids.length; i++) { horseItems[_ticketId].remove(_ids[i]); emit HorseItemRemoved(_ticketId, _ids[i]); } } function removeAllHorseItems(uint8 _ticketId) external operatorOrOwner { delete horseItems[_ticketId]; } function swap(SwapData memory _data) external { require( swappedItemIds[_data.uniqueId].horseItemIds.length == 0, "SwapTicket: Unique ID already used" ); verifySwap(msg.sender, _data); uint256[] memory horseItemIds = new uint256[](_data.horseItemAmount); for (uint8 i = 0; i < _data.horseItemAmount; i++) { uint256 horseId = getRandomHorseId( _data.uniqueId, _data.tokenId, i ); horseItems[_data.tokenId].remove(horseId); horseItemIds[i] = horseId; } ticket.burn(msg.sender, _data.tokenId, _data.tokenAmount); horseItemNFT.multiTransfer(msg.sender, horseItemIds); swappedItemIds[_data.uniqueId] = SwappedItems({ horseItemAddress: address(horseItemNFT), horseItemIds: horseItemIds }); emit HorseItemsSwapped( _data.uniqueId, address(ticket), _data.tokenId, _data.tokenAmount, msg.sender, horseItemIds, _data.userId ); } function withdrawHorseItems( uint8 _ticketLength, uint256[] calldata _ids, address _to ) external operatorOrOwner { require(_to != address(0), "SwapTicket: zero address"); uint256 limitHorseItem = 50; require( _ids.length <= limitHorseItem, "SwapTicket: Exceeds limit of horse items" ); for (uint256 i = 0; i < _ids.length; ++i) { for (uint8 j = 1; j <= _ticketLength; ++j) { horseItems[j].remove(_ids[i]); } } horseItemNFT.multiTransfer(_to, _ids); } function getRandomHorseId( uint256 _uniqueId, uint8 _tokenId, uint8 _randomIndex ) internal view returns (uint256) { require( horseItems[_tokenId].length() > 0, "SwapTicket: No horse items available for type" ); uint256 index = uint256( keccak256( abi.encodePacked(_uniqueId, block.timestamp, _randomIndex) ) ) % horseItems[_tokenId].length(); return horseItems[_tokenId].at(index); } // View functions function getHorseItemNFT() external view returns (IHorseItemNFT) { return horseItemNFT; } function getTicket() external view returns (ITicket) { return ticket; } function getTotalHorseNFT(uint8 _ticketId) external view returns (uint256) { return horseItems[_ticketId].length(); } function getHorseItems( uint8 _ticketId ) external view returns (uint256[] memory) { return horseItems[_ticketId].values(); } function getSwappedItemIds( uint256 _uniqueId ) external view returns (SwappedItems memory) { return swappedItemIds[_uniqueId]; } function getMultipleSwappedItemIds( uint256[] memory _uniqueIds ) external view returns (SwappedItems[] memory) { SwappedItems[] memory items = new SwappedItems[](_uniqueIds.length); for (uint256 i = 0; i < _uniqueIds.length; i++) { items[i] = swappedItemIds[_uniqueIds[i]]; } return items; } function verifySwap(address _sender, SwapData memory _data) internal view { bytes32 message = keccak256( abi.encode( _sender, _data.uniqueId, _data.tokenId, _data.tokenAmount, _data.horseItemAmount, _data.userId, _data.timestamp ) ); address signer = message.toString().recover(_data.v, _data.r, _data.s); require( block.timestamp <= _data.timestamp + timeExpiredSignature, "SwapTicket: signature expired" ); require(signer == signerAddress, "SwapTicket: Invalid signature"); } function multiTransfer( address to, uint256[] memory tokenIds ) external operatorOrOwner { require(to != address(0), "SwapTicket: zero address"); for (uint256 i = 0; i < tokenIds.length; i++) { require( horseItemNFT.ownerOf(tokenIds[i]) == address(this), "SwapTicket: contract does not own the token" ); horseItemNFT.safeTransferFrom(address(this), to, tokenIds[i]); } } function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) public override returns (bytes4) { setHorseItem(horseForTicket, tokenId); return this.onERC721Received.selector; } }
ABI-encoded Constructor Arguments (if required by the contract)
Add arguments in
ABI hex encoded form
. Constructor arguments are written right to left, and will be found at the end of the input created bytecode. They may also be
parsed here.
Loading...
Verify & publish
Cancel
Ok
Ok
Ok
No
Yes