ERC-721
Overview
Max Total Supply
0 MA
Holders
577
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
5 MALoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
MechanizedAbstractions
Compiler Version
v0.8.0+commit.c7dfd78e
Optimization Enabled:
Yes with 1 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol"; // Opensea: represents a proxy contract of a user contract OwnableDelegateProxy {} /** Opensea: This represents Opensea's ProxyRegistry contract. We use it to find and approve the opensea proxy contract of a user so our contract is better integrated with opensea. */ contract ProxyRegistry { mapping(address => OwnableDelegateProxy) public proxies; } contract MechanizedAbstractions is AccessControl, Ownable, ERC721, VRFConsumerBase { using SafeMath for uint256; using Strings for uint256; using ECDSA for bytes32; // Addresses address public proxyRegistryAddress; // Opensea: the address of the Opensea ProxyRegistry // Strings string public p5ScriptArweaveAddress; // points to the p5 script on arweave https://55mcex7dtd5xf4c627v6hadwoq6lgw6jr4oeacqd5k2mazhunejq.arweave.net/71giX-OY-3LwXtfr44B2dDyzW8mPHEAKA-q0wGT0aRM string public baseURIString = ""; // represents the baseURI of the metadata string public p5script = "function mechanizedAbstractionRenderer(e){let[t,o]=function(e){const t=parseInt(e.slice(0,Math.floor(e.length/2)))%1e10,o=parseInt(e.slice(Math.floor(e.length/2),e.length))%1e10;return[t,o]}(e);var l,n,r,a,F,d,i,s,v,D,A,h=60,E=255,B={};let b={},c={'Mid-century':{v:['#F1B680','#E98355','#D24227','#274274','#4787A8','#89B6AB','#8AAAA2'],w:7,bbl:['#D24227','#F1B680','#E98355']},Unpacked:{v:['#00000B','#87F8DF','#DE4338','#F4C0D9','#2E34C5','#E7E96D'],w:7,bbl:[]},Boardwalk:{v:['#B8E2D3','#5B9AF5','#FD2B73','#FE8233','#D40C0C','#FFCA35','#1F7340','#0343C1','#66093E'],w:3,bbl:['#5B9AF5','#FE8233','#D40C0C','#FFCA35','#1F7340','#0343C1','#66093E']},'Pop!':{v:['#E7147F','#179AED','#2C2A87','#F4EF19','#7A4A95','#9DD340','#DC132A'],w:6,bbl:['#DC132A','#']},Sunburst:{v:['#143642','#ec9a29','#0f8b8d','#dad2d8'],w:3,bbl:[]},Ethereal:{v:['#03B87A','#6139D0','#60A0F4','#FFDE3A','#F4FCFF','#2A2F4D','#F6C1FF'],w:7,bbl:['#FFDE3A','#F6C1FF']},Coral:{v:['#FF8A71','#DB82A8','#55BCF5','#7CD3C5','#0246C9','#FFBAAB'],w:5,bbl:[]},Paradise:{v:['#FD9672','#FAA34F','#6BACB5','#3F7088','#EDC1BE'],w:4,bbl:['#FD9672','#FAA34F']},'Ultra Red':{v:['#313B42','#FFEEE4','#E54F2D','#FD7A6E','#FFBDB7'],w:4,bbl:['#E54F2D','']},'Ocean Blues':{v:['#3073AD','#78B0E2','#9CC2E3','#D9EDFF','#0788D9'],w:2,bbl:['#D94F30']},Dreamscape:{v:['#E0CEFA','#88A0E4','#5991FF','#FFA794','#FF8282','#B9FDDD'],w:5,bbl:['#FFA794','#FF8282']},Blossom:{v:['#2A764B','#55A578','#F5F5D9','#FFC4B2','#DC934C'],w:3,bbl:['','','']},Mystique:{v:['#A57AFF','#C4F500','#03CCBF','#80FFD4','#03A0FF','#0469A6','#30337A'],w:5,bbl:['#03A0FF','#C4F500']},Nautical:{v:['#FAC998','#EB9C44','#D9492A','#A12425','#347D95'],w:4,bbl:['#D9492A','#EB9C44']},Retro:{v:['#F4EE97','#F9D74D','#EC9E43','#E2693C','#4A6076'],w:2,bbl:['#','#']},'Ode to Van Gogh':{v:['#2A4184','#5A87C2','#94C0D2','#EFE986','#1B2424'],w:3,bbl:['#EFE986']},'Ode to Mondrian':{v:['#D2BA49','#B7B8B2','#143675','#9E2F2A','#DDDDD9'],w:3,bbl:['#9E2F2A','#143675']},'Ode to Monet':{v:['#C4C7BA','#344147','#6A8993','#D46E60','#D18D74'],w:3,bbl:['#D46E60']},'Midnight Blue':{v:['#000421','#1BC5D2'],w:2,bbl:['#1BC5D2']},Monochrome:{v:['#F0EFEF','#373737'],w:2},Punkable:{v:['#6C91A6','#D77247','#CBEDEC','#FFF0B5','#313131','#9BC989','#BEBEBE'],w:3,bbl:['#D77247']},Apeable:{v:['#9A9B6B','#B9CBDC','#F3B468','#396785','#74D4B4','#9979A0','#F2F29C'],w:3,bbl:['#ED041F']}},w={Solid:{v:'solid',w:80},Translucent:{v:'translucent',w:20}},m={Low:{v:{mean:15,std:5,floor:20},w:60},Medium:{v:{mean:30,std:5,floor:20},w:20},High:{v:{mean:40,std:5,floor:20},w:10}},C={None:{v:0,w:89},Thick:{v:1.5,w:10},Thin:{v:1,w:1}},u={White:{v:'rgba(255,255,255,.8)',w:1},Black:{v:'rgba(0,0,0,.6)',w:1}},f={Short:{v:{mean:200,std:150},w:1},Normal:{v:{mean:400,std:300},w:1},Long:{v:{mean:1500,std:250},w:1}},g={Thin:{v:{mean:3,std:.1},w:25},Normal:{v:{mean:10,std:5},w:60},Thick:{v:{mean:20,std:5},w:15}},p={Normal:{v:2e-4,w:85},Straight:{v:1e-6,w:15}},k={Normal:{v:{mean:25e3,std:25e3},w:1},None:{v:{mean:0,std:0},w:1}},M={'No Border':{v:-25,w:85},Border:{v:35,w:15}};var S=function(e,t){var o=Object.keys(e),l=[];for(let t=0;t<o.length;t++){let n=e[o[t]].w;for(let e=0;e<n;e++)l.push(o[t])}return l[t.floor(t.random()*l.length)]};function y(e,t,o,l){let n=e.randomGaussian(2,10);var r=[],a=[];for(var F=0;F<13;F++){let l=n+e.random(-n/35,n/35);r[F]=t+l*e.cos(360*F/13),a[F]=o+l*e.sin(360*F/13)}e.beginShape();for(let t=0;t<r.length;t++)e.curveVertex(r[t],a[t]);e.endShape(e.CLOSE)}function x(e,t,o){let l=o.randomGaussian(D,10);return e<l||e>o.width-l||t<l||t>o.height-l}function N(e,t,o){let l=e.randomGaussian(i.mean,i.std),n=e.randomGaussian(s.mean,s.std);var r=[],F=[];r.push(t);for(let t=0;t<l;t++){let o=e.createVector(r[t].x+n,r[t].y+n);if(x(r[t].x+n,r[t].y+n,e))--t,--l;else{F.push(o);var v=e.map(e.noise(r[t].x*d,r[t].y*d),0,1,0,720);if(x(r[t].x+e.cos(v),r[t].y+e.sin(v),e))--t,--l;else{var D=e.createVector(r[t].x+e.cos(v),r[t].y+e.sin(v));r.push(D)}}}for(e.beginShape(),t=0;t<r.length;t++){let o=r[t];e.vertex(o.x,o.y)}for(t=F.length-1;t>=0;t--){let o=F[t];e.vertex(o.x,o.y)}e.endShape(),e.stroke(a);let A=e.color(o);A.setAlpha(E),e.fill(A)}return{renderer:e=>{e.setup=function(){e.randomSeed(t),e.noiseSeed(o);let x=e.createCanvas(1500,500);var G;for(e.angleMode(e.DEGREES),function(e){B.randomSeed=t,B.noiseSeed=o;let v=S(w,e);B['fill type']=v,'translucent'==w[v].v&&(delete c.Monochrome,delete c['Midnight Blue'],delete C.Thick,delete m.Low,delete m.Medium,h=80,E=200);let b=S(M,e);B.borderStyle=b,(D=M[b].v)>0&&(delete m.Low,delete m.Medium);let y=S(m,e);B.density=y,F=m[y].v;let x=S(c,e);B.colors=x,l=c[x].v,n=c[x].bbl,'Midnight Blue'==x&&(delete u.Black,delete C.None,delete C.Thick),'Monochrome'==x&&(delete u.White,delete C.None,delete C.Thick);let N=S(C,e);B.strokeThickness=N,r=C[N].v;let G=S(u,e);B.strokeColor=G,a=u[G].v;let T=S(f,e);B.curveLength=T,i=f[T].v;let L=S(g,e);B.curveWidth=L,s=g[L].v;let O=S(p,e);B.curveRate=O,d=p[O].v;let R=S(k,e);B.textureDensity=R,A=k[R].v}(e);null==G;){let t=l[e.floor(e.random()*l.length)];null!=n&&n.includes(t)||(G=t)}e.background(G),l=l.filter(e=>e!=G),e.strokeWeight(r);let T=e.floor(e.max(e.randomGaussian(F.mean,F.std),F.floor));for(var L=e.width/T,O=D;O<e.width-D;O+=L)for(var R=D;R<e.height-D;R+=L)if(e.floor(100*e.random())<=h){var U=e.createVector(O+e.random(-10,10),R+e.random(-10,10));N(e,U,l[e.floor(e.random()*l.length)])}else e.random(),e.width,e.random(),e.height,y(e,O+e.randomGaussian(20,20),R+e.random(20,20),l[e.floor(e.random()*l.length)]);v=e.randomGaussian(A.mean,A.std),function(e,t){let o=e.floor(e.random(50,90)),l=e.color(20,20,20,o);e.noStroke(),e.fill(l);for(let o=0;o<t;o++){let t=e.random()*e.width,o=e.random()*e.height,l=e.random(0,1.5);e.ellipse(t,o,l)}}(e,v),b.dataUrl=x.canvas.toDataURL()},e.draw=function(){e.noLoop()}},properties:B,dataUrl:b}}"; string public arweaveGateway = "https://arweave.net/"; // Flags bool public isContractOpen = true; // Token data uint256 public nextTokenId = 1; /** ROLES */ bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); // Arweave metadata uint256[] public arweaveManifestBatches; // excluding the token of the value itself string[] public arweaveManifestIds; // Chainlink VRF variables bytes32 private keyHash; // public key used to generate random values uint256 private fee; // fee paid to chainlink node for random value uint256 public baseSeed = 0; // MechanizedAbstractions seed values mapping(uint256 => uint256) private _vrfValues; mapping(uint256 => uint256) public seedValues; // maps token id to seed value // events event Minted(address minter, uint256 tokenId); event VRFRequested(bytes32 requestId); event VRFReceived(bytes32 requestId); event ReceivedEther(uint256 amount, address _from); // modifiers modifier modifiable { require(isContractOpen, "NOT MODIFIABLE"); _; } constructor( string memory _name, string memory _symbol, address _proxyRegistryAddress, string memory _p5ScriptArweaveAddress, address _vrfCoordinator, address _linkTokenAddress, uint256 _vrfFee, bytes32 _keyHash ) Ownable() ERC721(_name, _symbol) VRFConsumerBase( _vrfCoordinator, _linkTokenAddress ) { proxyRegistryAddress = _proxyRegistryAddress; // set the provided ProxyRegistry address to our own state variable p5ScriptArweaveAddress = _p5ScriptArweaveAddress; // set arweave address of p5 script keyHash = _keyHash; // set the keyhash used for rng fee = _vrfFee; // fee paid to chainlink VRF node, varies per network (0.1 * 10 ** 18) = 0.1 link _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); } /** === ERC-721 & METADATA functions === */ /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControl, ERC721) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev returns the baseURI for the metadata. Used by the tokenURI method. * @return the URI of the metadata */ function _baseURI() internal override view returns (string memory) { return baseURIString; } /** * @dev returns the tokenUri of a token * First it checks if the token exists, if not it reverts * Then it tries to find the batch index of the token * If the batch index is not found it returns a link to the server * Otherwise it returns a link to the corresponding arweave manifest * * @param tokenId the tokenId of the token */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "TOKEN DOESN'T EXIST"); // Look for the arweave batch index of the token uint256 index = 0; bool found = false; for (uint i = 0; i < arweaveManifestBatches.length; i++) { if (tokenId < arweaveManifestBatches[i]) { index = i; found = true; break; } } // If no arweave manifest was uploaded for tokenId return a link to the server if (!found) { return string(abi.encodePacked(_baseURI(), tokenId.toString())); } // Otherwise return the arweave link return string(abi.encodePacked(arweaveGateway, arweaveManifestIds[index], "/", tokenId.toString())); } /** === ONLY OWNER === */ /** * @dev Allows the signatureProvider to set a new manifestId * for a given batch. * * @param batchId the batch Id * @param manifestId the manifest Id */ function setArweaveManifestId(uint256 batchId, string memory manifestId) external onlyOwner { if (arweaveManifestBatches.length > 0) { require(arweaveManifestBatches[arweaveManifestBatches.length - 1] < batchId, "BATCH ID SHOULD EXCEED PREVIOUS ONE"); } arweaveManifestBatches.push(batchId); arweaveManifestIds.push(manifestId); } function resetArweave() external onlyOwner modifiable { delete arweaveManifestBatches; delete arweaveManifestIds; } function setP5(string calldata _p5) external onlyOwner modifiable { p5script = _p5; } function setP5Address(string calldata _address) external onlyOwner modifiable { p5ScriptArweaveAddress = _address; } /** * @dev function to change the baseURI of the metadata */ function setBaseURI(string memory _newBaseURI) public onlyOwner modifiable { baseURIString = _newBaseURI; } function setArweaveGateway(string calldata _gateway) external onlyOwner modifiable { arweaveGateway = _gateway; } /** * @dev Allows the owner to withdraw link */ function withdrawLink() external onlyOwner { require(LINK.transfer(msg.sender, LINK.balanceOf(address(this))), "LINK Transfer failed"); } /** * @dev Allows the owner to withdraw ether */ function withdrawEth() external onlyOwner { (bool success, ) = msg.sender.call{value: address(this).balance}(""); require(success, "ETH Transfer failed"); } function disableModifications() external onlyOwner { isContractOpen = false; } /** === OPENSEA FUNCTIONS === */ /** * @dev Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings. */ function isApprovedForAll(address owner, address operator) override public view returns (bool) { // Create an instance of the ProxyRegistry contract from Opensea ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); // whitelist the ProxyContract of the owner of the NFT if (address(proxyRegistry.proxies(owner)) == operator) { return true; } return super.isApprovedForAll(owner, operator); } /** === MINT METHODS === */ /** * @dev mints numberOfTokens tokens. * - A new VRF request is made before each 15 tokens are minted * - Creates a new tokenData struct * - Increments the tokenId * - Checks if the VRF value for this batch is ready * - If so it mints the token * - If not it adds to token to pending mints array for current requestId * - And it adds one to the pending mints of the users * * @param numberOfTokens the number of tokens to mint */ function doMint(uint256 numberOfTokens, address _to) external onlyRole(MINTER_ROLE) { for (uint i = 0; i < numberOfTokens; i++) { _safeMint(_to, nextTokenId); seedValues[nextTokenId] = (uint256(keccak256(abi.encode(nextTokenId, baseSeed, msg.sender, block.timestamp, blockhash(block.number))))); emit Minted(_to, nextTokenId); nextTokenId = nextTokenId.add(1); } } function burn(uint256 tokenId) external onlyRole(BURNER_ROLE) { _burn(tokenId); } /** === CHAINLINK VRF METHODS === */ /** * Requests randomness */ function _requestNewVRN() external onlyOwner modifiable returns (bytes32) { require(LINK.balanceOf(address(this)) >= fee, "NOT ENOUGH LINK"); bytes32 requestId = requestRandomness(keyHash, fee); emit VRFRequested(requestId); return requestId; } /** * @dev Callback function used by VRF Coordinator * Pushed new VRF value to array * Mints any pending tokens */ function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override { baseSeed = randomness; emit VRFReceived(requestId); } /** === MISC === */ /** * @dev Fallback function for receiving Ether */ receive() external payable { emit ReceivedEther(msg.value, msg.sender); } /** * @dev returns the amount fo arweave batches that have been uploaded */ function arweaveBatchLength() external view returns(uint256) { return arweaveManifestBatches.length; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @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. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits a {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.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 Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing 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 v4.4.0 (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/LinkTokenInterface.sol"; import "./VRFRequestIDBase.sol"; /** **************************************************************************** * @notice Interface for contracts using VRF randomness * ***************************************************************************** * @dev PURPOSE * * @dev Reggie the Random Oracle (not his real job) wants to provide randomness * @dev to Vera the verifier in such a way that Vera can be sure he's not * @dev making his output up to suit himself. Reggie provides Vera a public key * @dev to which he knows the secret key. Each time Vera provides a seed to * @dev Reggie, he gives back a value which is computed completely * @dev deterministically from the seed and the secret key. * * @dev Reggie provides a proof by which Vera can verify that the output was * @dev correctly computed once Reggie tells it to her, but without that proof, * @dev the output is indistinguishable to her from a uniform random sample * @dev from the output space. * * @dev The purpose of this contract is to make it easy for unrelated contracts * @dev to talk to Vera the verifier about the work Reggie is doing, to provide * @dev simple access to a verifiable source of randomness. * ***************************************************************************** * @dev USAGE * * @dev Calling contracts must inherit from VRFConsumerBase, and can * @dev initialize VRFConsumerBase's attributes in their constructor as * @dev shown: * * @dev contract VRFConsumer { * @dev constuctor(<other arguments>, address _vrfCoordinator, address _link) * @dev VRFConsumerBase(_vrfCoordinator, _link) public { * @dev <initialization with other arguments goes here> * @dev } * @dev } * * @dev The oracle will have given you an ID for the VRF keypair they have * @dev committed to (let's call it keyHash), and have told you the minimum LINK * @dev price for VRF service. Make sure your contract has sufficient LINK, and * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you * @dev want to generate randomness from. * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomness method. * * @dev The randomness argument to fulfillRandomness is the actual random value * @dev generated from your seed. * * @dev The requestId argument is generated from the keyHash and the seed by * @dev makeRequestId(keyHash, seed). If your contract could have concurrent * @dev requests open, you can use the requestId to track which seed is * @dev associated with which randomness. See VRFRequestIDBase.sol for more * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind, * @dev if your contract could have multiple requests in flight simultaneously.) * * @dev Colliding `requestId`s are cryptographically impossible as long as seeds * @dev differ. (Which is critical to making unpredictable randomness! See the * @dev next section.) * * ***************************************************************************** * @dev SECURITY CONSIDERATIONS * * @dev A method with the ability to call your fulfillRandomness method directly * @dev could spoof a VRF response with any random value, so it's critical that * @dev it cannot be directly called by anything other than this base contract * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method). * * @dev For your users to trust that your contract's random behavior is free * @dev from malicious interference, it's best if you can write it so that all * @dev behaviors implied by a VRF response are executed *during* your * @dev fulfillRandomness method. If your contract must store the response (or * @dev anything derived from it) and use it later, you must ensure that any * @dev user-significant behavior which depends on that stored value cannot be * @dev manipulated by a subsequent VRF request. * * @dev Similarly, both miners and the VRF oracle itself have some influence * @dev over the order in which VRF responses appear on the blockchain, so if * @dev your contract could have multiple VRF requests in flight simultaneously, * @dev you must ensure that the order in which the VRF responses arrive cannot * @dev be used to manipulate your contract's user-significant behavior. * * @dev Since the ultimate input to the VRF is mixed with the block hash of the * @dev block in which the request is made, user-provided seeds have no impact * @dev on its economic security properties. They are only included for API * @dev compatability with previous versions of this contract. * * @dev Since the block hash of the block which contains the requestRandomness * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful * @dev miner could, in principle, fork the blockchain to evict the block * @dev containing the request, forcing the request to be included in a * @dev different block with a different hash, and therefore a different input * @dev to the VRF. However, such an attack would incur a substantial economic * @dev cost. This cost scales with the number of blocks the VRF oracle waits * @dev until it calls responds to a request. */ abstract contract VRFConsumerBase is VRFRequestIDBase { /** * @notice fulfillRandomness handles the VRF response. Your contract must * @notice implement it. See "SECURITY CONSIDERATIONS" above for important * @notice principles to keep in mind when implementing your fulfillRandomness * @notice method. * * @dev VRFConsumerBase expects its subcontracts to have a method with this * @dev signature, and will call it once it has verified the proof * @dev associated with the randomness. (It is triggered via a call to * @dev rawFulfillRandomness, below.) * * @param requestId The Id initially returned by requestRandomness * @param randomness the VRF output */ function fulfillRandomness( bytes32 requestId, uint256 randomness ) internal virtual; /** * @dev In order to keep backwards compatibility we have kept the user * seed field around. We remove the use of it because given that the blockhash * enters later, it overrides whatever randomness the used seed provides. * Given that it adds no security, and can easily lead to misunderstandings, * we have removed it from usage and can now provide a simpler API. */ uint256 constant private USER_SEED_PLACEHOLDER = 0; /** * @notice requestRandomness initiates a request for VRF output given _seed * * @dev The fulfillRandomness method receives the output, once it's provided * @dev by the Oracle, and verified by the vrfCoordinator. * * @dev The _keyHash must already be registered with the VRFCoordinator, and * @dev the _fee must exceed the fee specified during registration of the * @dev _keyHash. * * @dev The _seed parameter is vestigial, and is kept only for API * @dev compatibility with older versions. It can't *hurt* to mix in some of * @dev your own randomness, here, but it's not necessary because the VRF * @dev oracle will mix the hash of the block containing your request into the * @dev VRF seed it ultimately uses. * * @param _keyHash ID of public key against which randomness is generated * @param _fee The amount of LINK to send with the request * * @return requestId unique ID for this request * * @dev The returned requestId can be used to distinguish responses to * @dev concurrent requests. It is passed as the first argument to * @dev fulfillRandomness. */ function requestRandomness( bytes32 _keyHash, uint256 _fee ) internal returns ( bytes32 requestId ) { LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER)); // This is the seed passed to VRFCoordinator. The oracle will mix this with // the hash of the block containing this request to obtain the seed/input // which is finally passed to the VRF cryptographic machinery. uint256 vRFSeed = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]); // nonces[_keyHash] must stay in sync with // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest). // This provides protection against the user repeating their input seed, // which would result in a predictable/duplicate output, if multiple such // requests appeared in the same block. nonces[_keyHash] = nonces[_keyHash] + 1; return makeRequestId(_keyHash, vRFSeed); } LinkTokenInterface immutable internal LINK; address immutable private vrfCoordinator; // Nonces for each VRF key from which randomness has been requested. // // Must stay in sync with VRFCoordinator[_keyHash][this] mapping(bytes32 /* keyHash */ => uint256 /* nonce */) private nonces; /** * @param _vrfCoordinator address of VRFCoordinator contract * @param _link address of LINK token contract * * @dev https://docs.chain.link/docs/link-token-contracts */ constructor( address _vrfCoordinator, address _link ) { vrfCoordinator = _vrfCoordinator; LINK = LinkTokenInterface(_link); } // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomness( bytes32 requestId, uint256 randomness ) external { require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill"); fulfillRandomness(requestId, randomness); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.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`, 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 be 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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * 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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Address.sol) 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); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (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.0 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (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 // OpenZeppelin Contracts v4.4.0 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface LinkTokenInterface { function allowance( address owner, address spender ) external view returns ( uint256 remaining ); function approve( address spender, uint256 value ) external returns ( bool success ); function balanceOf( address owner ) external view returns ( uint256 balance ); function decimals() external view returns ( uint8 decimalPlaces ); function decreaseApproval( address spender, uint256 addedValue ) external returns ( bool success ); function increaseApproval( address spender, uint256 subtractedValue ) external; function name() external view returns ( string memory tokenName ); function symbol() external view returns ( string memory tokenSymbol ); function totalSupply() external view returns ( uint256 totalTokensIssued ); function transfer( address to, uint256 value ) external returns ( bool success ); function transferAndCall( address to, uint256 value, bytes calldata data ) external returns ( bool success ); function transferFrom( address from, address to, uint256 value ) external returns ( bool success ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract VRFRequestIDBase { /** * @notice returns the seed which is actually input to the VRF coordinator * * @dev To prevent repetition of VRF output due to repetition of the * @dev user-supplied seed, that seed is combined in a hash with the * @dev user-specific nonce, and the address of the consuming contract. The * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in * @dev the final seed, but the nonce does protect against repetition in * @dev requests which are included in a single block. * * @param _userSeed VRF seed input provided by user * @param _requester Address of the requesting contract * @param _nonce User-specific nonce at the time of the request */ function makeVRFInputSeed( bytes32 _keyHash, uint256 _userSeed, address _requester, uint256 _nonce ) internal pure returns ( uint256 ) { return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce))); } /** * @notice Returns the id for this request * @param _keyHash The serviceAgreement ID to be used for this request * @param _vRFInputSeed The seed to be passed directly to the VRF * @return The id for this request * * @dev Note that _vRFInputSeed is not the seed passed by the consuming * @dev contract, but the one generated by makeVRFInputSeed */ function makeRequestId( bytes32 _keyHash, uint256 _vRFInputSeed ) internal pure returns ( bytes32 ) { return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed)); } }
{ "optimizer": { "enabled": true, "runs": 1 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_proxyRegistryAddress","type":"address"},{"internalType":"string","name":"_p5ScriptArweaveAddress","type":"string"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_linkTokenAddress","type":"address"},{"internalType":"uint256","name":"_vrfFee","type":"uint256"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Minted","type":"event"},{"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":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_from","type":"address"}],"name":"ReceivedEther","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"VRFReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"VRFRequested","type":"event"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_requestNewVRN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"arweaveBatchLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"arweaveGateway","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"arweaveManifestBatches","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"arweaveManifestIds","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseSeed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURIString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableModifications","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"doMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isContractOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","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":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"p5ScriptArweaveAddress","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"p5script","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyRegistryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetArweave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"seedValues","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_gateway","type":"string"}],"name":"setArweaveGateway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"batchId","type":"uint256"},{"internalType":"string","name":"manifestId","type":"string"}],"name":"setArweaveManifestId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_p5","type":"string"}],"name":"setP5","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_address","type":"string"}],"name":"setP5Address","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e06040819052600060c08190526200001b91600b91620002ae565b506040518061170001604052806116c2815260200162003b146116c2913980516200004f91600c91602090910190620002ae565b506040805180820190915260148082527f68747470733a2f2f617277656176652e6e65742f00000000000000000000000060209092019182526200009691600d91620002ae565b50600e805460ff19166001908117909155600f556000601455348015620000bc57600080fd5b50604051620051d6380380620051d6833981016040819052620000df916200041c565b83838989620000f7620000f162000195565b62000199565b81516200010c906002906020850190620002ae565b50805162000122906003906020840190620002ae565b505050606091821b6001600160601b031990811660a052911b16608052600980546001600160a01b0319166001600160a01b03881617905584516200016f90600a906020880190620002ae565b506012819055601382905562000187600033620001eb565b505050505050505062000547565b3390565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620001f78282620001fb565b5050565b62000207828262000285565b620001f7576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556200024162000195565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b828054620002bc90620004f4565b90600052602060002090601f016020900481019282620002e057600085556200032b565b82601f10620002fb57805160ff19168380011785556200032b565b828001600101855582156200032b579182015b828111156200032b5782518255916020019190600101906200030e565b50620003399291506200033d565b5090565b5b808211156200033957600081556001016200033e565b80516001600160a01b03811681146200036c57600080fd5b919050565b600082601f83011262000382578081fd5b81516001600160401b03808211156200039f576200039f62000531565b6040516020601f8401601f1916820181018381118382101715620003c757620003c762000531565b6040528382528584018101871015620003de578485fd5b8492505b83831015620004015785830181015182840182015291820191620003e2565b838311156200041257848185840101525b5095945050505050565b600080600080600080600080610100898b03121562000439578384fd5b88516001600160401b038082111562000450578586fd5b6200045e8c838d0162000371565b995060208b015191508082111562000474578586fd5b620004828c838d0162000371565b98506200049260408c0162000354565b975060608b0151915080821115620004a8578586fd5b50620004b78b828c0162000371565b955050620004c860808a0162000354565b9350620004d860a08a0162000354565b60c08a015160e0909a0151989b979a5095989497939692505050565b6002810460018216806200050957607f821691505b602082108114156200052b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b60805160601c60a05160601c61358c62000588600039600081816113340152611d04015260008181610dd2015281816111e40152611cd5015261358c6000f3fe6080604052600436106102325760003560e01c806301ffc9a71461027757806304da5304146102ad57806306fdde03146102cf57806307ba3196146102f1578063081812fc14610306578063095ea7b31461033357806314d53c25146103535780631c8a173914610380578063231871d6146103a057806323b872dd146103b5578063248a9ca3146103d5578063282c51f3146103f55780632d2b26ee1461040a5780632f2ff15d1461042a57806336568abe1461044a578063374145ce1461046a57806342842e0e1461048a57806342966c68146104aa5780634417d216146104ca5780634f638a40146104df578063506eb3f8146104ff57806355f804b3146105145780635b2906d0146105345780636352211e146105495780636602529214610569578063684297de1461057e57806370a0823114610593578063715018a6146105b357806375794a3c146105c85780638da5cb5b146105dd5780638dc654a2146105f257806391d148541461060757806394985ddd1461062757806395d89b41146106475780639e8ed6f71461065c578063a0ef91df14610671578063a217fddf14610686578063a22cb4651461069b578063b07fe3a1146106bb578063b88d4fde146106d0578063c8321c78146106f0578063c87b56dd14610710578063cd7c032614610730578063cf76a15314610745578063d53913931461075a578063d547741f1461076f578063e985e9c51461078f578063f2bfb811146107af578063f2fde38b146107cf57610272565b36610272577ffc0190751e68e3a764092e8161dc292f90c0e10e38ddf16a6b42670667bcac47343360405161026892919061331d565b60405180910390a1005b600080fd5b34801561028357600080fd5b50610297610292366004612957565b6107ef565b6040516102a49190612cee565b60405180910390f35b3480156102b957600080fd5b506102cd6102c83660046129ab565b610852565b005b3480156102db57600080fd5b506102e46108cd565b6040516102a49190612d26565b3480156102fd57600080fd5b506102e461095f565b34801561031257600080fd5b506103266103213660046128fa565b6109ed565b6040516102a49190612c54565b34801561033f57600080fd5b506102cd61034e3660046128b3565b610a30565b34801561035f57600080fd5b5061037361036e3660046128fa565b610ac3565b6040516102a49190612cf9565b34801561038c57600080fd5b506102cd61039b3660046129ab565b610ad5565b3480156103ac57600080fd5b50610373610b42565b3480156103c157600080fd5b506102cd6103d03660046127ca565b610b48565b3480156103e157600080fd5b506103736103f03660046128fa565b610b80565b34801561040157600080fd5b50610373610b95565b34801561041657600080fd5b506102cd610425366004612912565b610ba7565b34801561043657600080fd5b506102cd610445366004612912565b610c86565b34801561045657600080fd5b506102cd610465366004612912565b610ca5565b34801561047657600080fd5b506102e46104853660046128fa565b610ceb565b34801561049657600080fd5b506102cd6104a53660046127ca565b610d16565b3480156104b657600080fd5b506102cd6104c53660046128fa565b610d31565b3480156104d657600080fd5b50610373610d55565b3480156104eb57600080fd5b506102cd6104fa366004612a61565b610ec3565b34801561050b57600080fd5b506102e4610fd3565b34801561052057600080fd5b506102cd61052f366004612a17565b610fe0565b34801561054057600080fd5b50610297611054565b34801561055557600080fd5b506103266105643660046128fa565b61105d565b34801561057557600080fd5b506102cd611092565b34801561058a57600080fd5b506102e46110dd565b34801561059f57600080fd5b506103736105ae366004612776565b6110ea565b3480156105bf57600080fd5b506102cd61112e565b3480156105d457600080fd5b50610373611179565b3480156105e957600080fd5b5061032661117f565b3480156105fe57600080fd5b506102cd61118e565b34801561061357600080fd5b50610297610622366004612912565b6112fe565b34801561063357600080fd5b506102cd610642366004612936565b611329565b34801561065357600080fd5b506102e461137b565b34801561066857600080fd5b5061037361138a565b34801561067d57600080fd5b506102cd611390565b34801561069257600080fd5b5061037361144e565b3480156106a757600080fd5b506102cd6106b6366004612886565b611453565b3480156106c757600080fd5b506102cd611465565b3480156106dc57600080fd5b506102cd6106eb36600461280a565b6114de565b3480156106fc57600080fd5b506102cd61070b3660046129ab565b611517565b34801561071c57600080fd5b506102e461072b3660046128fa565b611584565b34801561073c57600080fd5b506103266116ac565b34801561075157600080fd5b506102e46116bb565b34801561076657600080fd5b506103736116c8565b34801561077b57600080fd5b506102cd61078a366004612912565b6116da565b34801561079b57600080fd5b506102976107aa366004612792565b6116f9565b3480156107bb57600080fd5b506103736107ca3660046128fa565b6117ad565b3480156107db57600080fd5b506102cd6107ea366004612776565b6117ce565b60006001600160e01b031982166380ac58cd60e01b148061082057506001600160e01b03198216635b5e139f60e01b145b8061083b57506001600160e01b03198216637965db0b60e01b145b8061084a575061084a8261183c565b90505b919050565b61085a61187c565b6001600160a01b031661086b61117f565b6001600160a01b03161461089a5760405162461bcd60e51b815260040161089190613159565b60405180910390fd5b600e5460ff166108bc5760405162461bcd60e51b815260040161089190613087565b6108c8600a8383612546565b505050565b6060600280546108dc90613411565b80601f016020809104026020016040519081016040528092919081815260200182805461090890613411565b80156109555780601f1061092a57610100808354040283529160200191610955565b820191906000526020600020905b81548152906001019060200180831161093857829003601f168201915b5050505050905090565b600a805461096c90613411565b80601f016020809104026020016040519081016040528092919081815260200182805461099890613411565b80156109e55780601f106109ba576101008083540402835291602001916109e5565b820191906000526020600020905b8154815290600101906020018083116109c857829003601f168201915b505050505081565b60006109f882611880565b610a145760405162461bcd60e51b81526004016108919061310d565b506000908152600660205260409020546001600160a01b031690565b6000610a3b8261105d565b9050806001600160a01b0316836001600160a01b03161415610a6f5760405162461bcd60e51b81526004016108919061320e565b806001600160a01b0316610a8161187c565b6001600160a01b03161480610a9d5750610a9d816107aa61187c565b610ab95760405162461bcd60e51b815260040161089190612f9c565b6108c8838361189d565b60166020526000908152604090205481565b610add61187c565b6001600160a01b0316610aee61117f565b6001600160a01b031614610b145760405162461bcd60e51b815260040161089190613159565b600e5460ff16610b365760405162461bcd60e51b815260040161089190613087565b6108c8600d8383612546565b60105490565b610b59610b5361187c565b8261190b565b610b755760405162461bcd60e51b81526004016108919061324f565b6108c8838383611988565b60009081526020819052604090206001015490565b6000805160206134f783398151915281565b600080516020613517833981519152610bc781610bc261187c565b611aa3565b60005b83811015610c8057610bde83600f54611b07565b600f5460145433424340604051602001610bfc959493929190613334565b60408051601f198184030181528282528051602091820120600f8054600090815260169093529290912055547f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe91610c55918691612ca5565b60405180910390a1600f54610c6b906001611b21565b600f5580610c788161344c565b915050610bca565b50505050565b610c8f82610b80565b610c9b81610bc261187c565b6108c88383611b34565b610cad61187c565b6001600160a01b0316816001600160a01b031614610cdd5760405162461bcd60e51b8152600401610891906132ce565b610ce78282611bb9565b5050565b60118181548110610cfb57600080fd5b90600052602060002001600091509050805461096c90613411565b6108c8838383604051806020016040528060008152506114de565b6000805160206134f7833981519152610d4c81610bc261187c565b610ce782611c3c565b6000610d5f61187c565b6001600160a01b0316610d7061117f565b6001600160a01b031614610d965760405162461bcd60e51b815260040161089190613159565b600e5460ff16610db85760405162461bcd60e51b815260040161089190613087565b6013546040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610e07903090600401612c54565b60206040518083038186803b158015610e1f57600080fd5b505afa158015610e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e579190612a49565b1015610e755760405162461bcd60e51b8152600401610891906130af565b6000610e85601254601354611cd1565b90507f0a2d241dbb61e3eff8f8c6dd39c403577e294dd102fe1b2880ede8145656b1f681604051610eb69190612cf9565b60405180910390a1905090565b610ecb61187c565b6001600160a01b0316610edc61117f565b6001600160a01b031614610f025760405162461bcd60e51b815260040161089190613159565b60105415610f635760108054839190610f1d906001906133b7565b81548110610f3b57634e487b7160e01b600052603260045260246000fd5b906000526020600020015410610f635760405162461bcd60e51b815260040161089190612ee0565b6010805460018181019092557f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720183905560118054918201815560005281516108c8917f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68019060208401906125ca565b600c805461096c90613411565b610fe861187c565b6001600160a01b0316610ff961117f565b6001600160a01b03161461101f5760405162461bcd60e51b815260040161089190613159565b600e5460ff166110415760405162461bcd60e51b815260040161089190613087565b8051610ce790600b9060208401906125ca565b600e5460ff1681565b6000818152600460205260408120546001600160a01b03168061084a5760405162461bcd60e51b81526004016108919061303e565b61109a61187c565b6001600160a01b03166110ab61117f565b6001600160a01b0316146110d15760405162461bcd60e51b815260040161089190613159565b600e805460ff19169055565b600d805461096c90613411565b60006001600160a01b0382166111125760405162461bcd60e51b815260040161089190612ff4565b506001600160a01b031660009081526005602052604090205490565b61113661187c565b6001600160a01b031661114761117f565b6001600160a01b03161461116d5760405162461bcd60e51b815260040161089190613159565b6111776000611e0c565b565b600f5481565b6001546001600160a01b031690565b61119661187c565b6001600160a01b03166111a761117f565b6001600160a01b0316146111cd5760405162461bcd60e51b815260040161089190613159565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90339083906370a0823190611223903090600401612c54565b60206040518083038186803b15801561123b57600080fd5b505afa15801561124f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112739190612a49565b6040518363ffffffff1660e01b8152600401611290929190612ca5565b602060405180830381600087803b1580156112aa57600080fd5b505af11580156112be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e291906128de565b6111775760405162461bcd60e51b8152600401610891906132a0565b6000828152602081815260408083206001600160a01b038516845290915290205460ff165b92915050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113715760405162461bcd60e51b8152600401610891906131d7565b610ce78282611e5e565b6060600380546108dc90613411565b60145481565b61139861187c565b6001600160a01b03166113a961117f565b6001600160a01b0316146113cf5760405162461bcd60e51b815260040161089190613159565b6000336001600160a01b0316476040516113e890612be2565b60006040518083038185875af1925050503d8060008114611425576040519150601f19603f3d011682016040523d82523d6000602084013e61142a565b606091505b505090508061144b5760405162461bcd60e51b815260040161089190612f6f565b50565b600081565b610ce761145e61187c565b8383611e9f565b61146d61187c565b6001600160a01b031661147e61117f565b6001600160a01b0316146114a45760405162461bcd60e51b815260040161089190613159565b600e5460ff166114c65760405162461bcd60e51b815260040161089190613087565b6114d26010600061263e565b6111776011600061265c565b6114ef6114e961187c565b8361190b565b61150b5760405162461bcd60e51b81526004016108919061324f565b610c8084848484611f42565b61151f61187c565b6001600160a01b031661153061117f565b6001600160a01b0316146115565760405162461bcd60e51b815260040161089190613159565b600e5460ff166115785760405162461bcd60e51b815260040161089190613087565b6108c8600c8383612546565b606061158f82611880565b6115ab5760405162461bcd60e51b815260040161089190612d39565b60008060005b60105481101561160c57601081815481106115dc57634e487b7160e01b600052603260045260246000fd5b90600052602060002001548510156115fa578092506001915061160c565b806116048161344c565b9150506115b1565b508061164c5761161a611f75565b61162385611f84565b604051602001611634929190612b77565b6040516020818303038152906040529250505061084d565b600d6011838154811061166f57634e487b7160e01b600052603260045260246000fd5b9060005260206000200161168286611f84565b60405160200161169493929190612ba6565b60405160208183030381529060405292505050919050565b6009546001600160a01b031681565b600b805461096c90613411565b60008051602061351783398151915281565b6116e382610b80565b6116ef81610bc261187c565b6108c88383611bb9565b60095460405163c455279160e01b81526000916001600160a01b039081169190841690829063c455279190611732908890600401612c54565b60206040518083038186803b15801561174a57600080fd5b505afa15801561175e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611782919061298f565b6001600160a01b0316141561179b576001915050611323565b6117a5848461209e565b949350505050565b601081815481106117bd57600080fd5b600091825260209091200154905081565b6117d661187c565b6001600160a01b03166117e761117f565b6001600160a01b03161461180d5760405162461bcd60e51b815260040161089190613159565b6001600160a01b0381166118335760405162461bcd60e51b815260040161089190612ded565b61144b81611e0c565b60006001600160e01b031982166380ac58cd60e01b148061186d57506001600160e01b03198216635b5e139f60e01b145b8061084a575061084a826120cc565b3390565b6000908152600460205260409020546001600160a01b0316151590565b600081815260066020526040902080546001600160a01b0319166001600160a01b03841690811790915581906118d28261105d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061191682611880565b6119325760405162461bcd60e51b815260040161089190612f23565b600061193d8361105d565b9050806001600160a01b0316846001600160a01b031614806119785750836001600160a01b031661196d846109ed565b6001600160a01b0316145b806117a557506117a581856116f9565b826001600160a01b031661199b8261105d565b6001600160a01b0316146119c15760405162461bcd60e51b81526004016108919061318e565b6001600160a01b0382166119e75760405162461bcd60e51b815260040161089190612e69565b6119f28383836108c8565b6119fd60008261189d565b6001600160a01b0383166000908152600560205260408120805460019290611a269084906133b7565b90915550506001600160a01b0382166000908152600560205260408120805460019290611a5490849061336c565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b03868116918217909255915184939187169160008051602061353783398151915291a4505050565b611aad82826112fe565b610ce757611ac5816001600160a01b031660146120f1565b611ad08360206120f1565b604051602001611ae1929190612be5565b60408051601f198184030181529082905262461bcd60e51b825261089191600401612d26565b610ce78282604051806020016040528060008152506122a2565b6000611b2d828461336c565b9392505050565b611b3e82826112fe565b610ce7576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055611b7561187c565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b611bc382826112fe565b15610ce7576000828152602081815260408083206001600160a01b03851684529091529020805460ff19169055611bf861187c565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000611c478261105d565b9050611c55816000846108c8565b611c6060008361189d565b6001600160a01b0381166000908152600560205260408120805460019290611c899084906133b7565b909155505060008281526004602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020613537833981519152908390a45050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000084866000604051602001611d38929190612b69565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611d6593929190612cbe565b602060405180830381600087803b158015611d7f57600080fd5b505af1158015611d93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db791906128de565b50600083815260086020526040812054611dd6908590839030906122d5565b600085815260086020526040902054909150611df390600161336c565b6000858152600860205260409020556117a5848261230f565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60148190556040517f201bfd6a460f81d26c819af2ca157f01e3c82f32d4d322fa1715cb4a394203c590611e93908490612cf9565b60405180910390a15050565b816001600160a01b0316836001600160a01b03161415611ed15760405162461bcd60e51b815260040161089190612ead565b6001600160a01b0383811660008181526007602090815260408083209487168084529490915290819020805460ff1916851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190611f35908590612cee565b60405180910390a3505050565b611f4d848484611988565b611f5984848484612342565b610c805760405162461bcd60e51b815260040161089190612d9b565b6060600b80546108dc90613411565b606081611fa957506040805180820190915260018152600360fc1b602082015261084d565b8160005b8115611fd35780611fbd8161344c565b9150611fcc9050600a83613384565b9150611fad565b6000816001600160401b03811115611ffb57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612025576020820181803683370190505b5090505b84156117a55761203a6001836133b7565b9150612047600a86613467565b61205290603061336c565b60f81b81838151811061207557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612097600a86613384565b9450612029565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061084a575061084a8261245a565b60606000612100836002613398565b61210b90600261336c565b6001600160401b0381111561213057634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561215a576020820181803683370190505b509050600360fc1b8160008151811061218357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106121c057634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006121e4846002613398565b6121ef90600161336c565b90505b6001811115612283576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061223157634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061225557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361227c816133fa565b90506121f2565b508315611b2d5760405162461bcd60e51b815260040161089190612d66565b6122ac8383612473565b6122b96000848484612342565b6108c85760405162461bcd60e51b815260040161089190612d9b565b6000848484846040516020016122ee9493929190612d02565b60408051601f19818403018152919052805160209091012095945050505050565b60008282604051602001612324929190612b69565b60405160208183030381529060405280519060200120905092915050565b6000612356846001600160a01b0316612540565b1561245257836001600160a01b031663150b7a0261237261187c565b8786866040518563ffffffff1660e01b81526004016123949493929190612c68565b602060405180830381600087803b1580156123ae57600080fd5b505af19250505080156123de575060408051601f3d908101601f191682019092526123db91810190612973565b60015b612438573d80801561240c576040519150601f19603f3d011682016040523d82523d6000602084013e612411565b606091505b5080516124305760405162461bcd60e51b815260040161089190612d9b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506117a5565b5060016117a5565b6001600160e01b031981166301ffc9a760e01b14919050565b6001600160a01b0382166124995760405162461bcd60e51b8152600401610891906130d8565b6124a281611880565b156124bf5760405162461bcd60e51b815260040161089190612e33565b6124cb600083836108c8565b6001600160a01b03821660009081526005602052604081208054600192906124f490849061336c565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020613537833981519152908290a45050565b3b151590565b82805461255290613411565b90600052602060002090601f01602090048101928261257457600085556125ba565b82601f1061258d5782800160ff198235161785556125ba565b828001600101855582156125ba579182015b828111156125ba57823582559160200191906001019061259f565b506125c692915061267a565b5090565b8280546125d690613411565b90600052602060002090601f0160209004810192826125f857600085556125ba565b82601f1061261157805160ff19168380011785556125ba565b828001600101855582156125ba579182015b828111156125ba578251825591602001919060010190612623565b508054600082559060005260206000209081019061144b919061267a565b508054600082559060005260206000209081019061144b919061268f565b5b808211156125c6576000815560010161267b565b808211156125c65760006126a382826126ac565b5060010161268f565b5080546126b890613411565b6000825580601f106126ca575061144b565b601f01602090049060005260206000209081019061144b919061267a565b60006001600160401b0380841115612702576127026134a7565b604051601f8501601f191681016020018281118282101715612726576127266134a7565b60405284815291508183850186101561273e57600080fd5b8484602083013760006020868301015250509392505050565b600082601f830112612767578081fd5b611b2d838335602085016126e8565b600060208284031215612787578081fd5b8135611b2d816134bd565b600080604083850312156127a4578081fd5b82356127af816134bd565b915060208301356127bf816134bd565b809150509250929050565b6000806000606084860312156127de578081fd5b83356127e9816134bd565b925060208401356127f9816134bd565b929592945050506040919091013590565b6000806000806080858703121561281f578081fd5b843561282a816134bd565b9350602085013561283a816134bd565b92506040850135915060608501356001600160401b0381111561285b578182fd5b8501601f8101871361286b578182fd5b61287a878235602084016126e8565b91505092959194509250565b60008060408385031215612898578182fd5b82356128a3816134bd565b915060208301356127bf816134d2565b600080604083850312156128c5578182fd5b82356128d0816134bd565b946020939093013593505050565b6000602082840312156128ef578081fd5b8151611b2d816134d2565b60006020828403121561290b578081fd5b5035919050565b60008060408385031215612924578182fd5b8235915060208301356127bf816134bd565b60008060408385031215612948578182fd5b50508035926020909101359150565b600060208284031215612968578081fd5b8135611b2d816134e0565b600060208284031215612984578081fd5b8151611b2d816134e0565b6000602082840312156129a0578081fd5b8151611b2d816134bd565b600080602083850312156129bd578182fd5b82356001600160401b03808211156129d3578384fd5b818501915085601f8301126129e6578384fd5b8135818111156129f4578485fd5b866020828501011115612a05578485fd5b60209290920196919550909350505050565b600060208284031215612a28578081fd5b81356001600160401b03811115612a3d578182fd5b6117a584828501612757565b600060208284031215612a5a578081fd5b5051919050565b60008060408385031215612a73578182fd5b8235915060208301356001600160401b03811115612a8f578182fd5b612a9b85828601612757565b9150509250929050565b60008151808452612abd8160208601602086016133ce565b601f01601f19169290920160200192915050565b805460009060028104600180831680612aeb57607f831692505b6020808410821415612b0b57634e487b7160e01b86526022600452602486fd5b818015612b1f5760018114612b3057612b5d565b60ff19861689528489019650612b5d565b612b3988613360565b60005b86811015612b555781548b820152908501908301612b3c565b505084890196505b50505050505092915050565b918252602082015260400190565b60008351612b898184602088016133ce565b835190830190612b9d8183602088016133ce565b01949350505050565b6000612bbb612bb58387612ad1565b85612ad1565b602f60f81b81528351612bd58160018401602088016133ce565b0160010195945050505050565b90565b600076020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b82528351612c178160178501602088016133ce565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612c488160288401602088016133ce565b01602801949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612c9b90830184612aa5565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038516825283602083015260606040830152612ce56060830184612aa5565b95945050505050565b901515815260200190565b90815260200190565b93845260208401929092526001600160a01b03166040830152606082015260800190565b600060208252611b2d6020830184612aa5565b6020808252601390820152721513d2d153881113d154d389d50811561254d5606a1b604082015260600190565b6020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b604082015260600190565b60208082526023908201527f42415443482049442053484f554c44204558434545442050524556494f5553206040820152624f4e4560e81b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526013908201527211551208151c985b9cd9995c8819985a5b1959606a1b604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776040820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252600e908201526d4e4f54204d4f4449464941424c4560901b604082015260600190565b6020808252600f908201526e4e4f5420454e4f554748204c494e4b60881b604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252601f908201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c00604082015260600190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526014908201527313125392c8151c985b9cd9995c8819985a5b195960621b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b9182526001600160a01b0316602082015260400190565b94855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b60009081526020902090565b6000821982111561337f5761337f61347b565b500190565b60008261339357613393613491565b500490565b60008160001904831182151516156133b2576133b261347b565b500290565b6000828210156133c9576133c961347b565b500390565b60005b838110156133e95781810151838201526020016133d1565b83811115610c805750506000910152565b6000816134095761340961347b565b506000190190565b60028104600182168061342557607f821691505b6020821081141561344657634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156134605761346061347b565b5060010190565b60008261347657613476613491565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461144b57600080fd5b801515811461144b57600080fd5b6001600160e01b03198116811461144b57600080fdfe3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8489f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c420e3c344454a68d64da6eaabb0a3c9902d7cdcf884ca7519271eec4d79548164736f6c6343000800003366756e6374696f6e206d656368616e697a65644162737472616374696f6e52656e64657265722865297b6c65745b742c6f5d3d66756e6374696f6e2865297b636f6e737420743d7061727365496e7428652e736c69636528302c4d6174682e666c6f6f7228652e6c656e6774682f3229292925316531302c6f3d7061727365496e7428652e736c696365284d6174682e666c6f6f7228652e6c656e6774682f32292c652e6c656e677468292925316531303b72657475726e5b742c6f5d7d2865293b766172206c2c6e2c722c612c462c642c692c732c762c442c412c683d36302c453d3235352c423d7b7d3b6c657420623d7b7d2c633d7b274d69642d63656e74757279273a7b763a5b2723463142363830272c2723453938333535272c2723443234323237272c2723323734323734272c2723343738374138272c2723383942364142272c2723384141414132275d2c773a372c62626c3a5b2723443234323237272c2723463142363830272c2723453938333535275d7d2c556e7061636b65643a7b763a5b2723303030303042272c2723383746384446272c2723444534333338272c2723463443304439272c2723324533344335272c2723453745393644275d2c773a372c62626c3a5b5d7d2c426f61726477616c6b3a7b763a5b2723423845324433272c2723354239414635272c2723464432423733272c2723464538323333272c2723443430433043272c2723464643413335272c2723314637333430272c2723303334334331272c2723363630393345275d2c773a332c62626c3a5b2723354239414635272c2723464538323333272c2723443430433043272c2723464643413335272c2723314637333430272c2723303334334331272c2723363630393345275d7d2c27506f7021273a7b763a5b2723453731343746272c2723313739414544272c2723324332413837272c2723463445463139272c2723374134413935272c2723394444333430272c2723444331333241275d2c773a362c62626c3a5b2723444331333241272c2723275d7d2c53756e62757273743a7b763a5b2723313433363432272c2723656339613239272c2723306638623864272c2723646164326438275d2c773a332c62626c3a5b5d7d2c457468657265616c3a7b763a5b2723303342383741272c2723363133394430272c2723363041304634272c2723464644453341272c2723463446434646272c2723324132463444272c2723463643314646275d2c773a372c62626c3a5b2723464644453341272c2723463643314646275d7d2c436f72616c3a7b763a5b2723464638413731272c2723444238324138272c2723353542434635272c2723374344334335272c2723303234364339272c2723464642414142275d2c773a352c62626c3a5b5d7d2c50617261646973653a7b763a5b2723464439363732272c2723464141333446272c2723364241434235272c2723334637303838272c2723454443314245275d2c773a342c62626c3a5b2723464439363732272c2723464141333446275d7d2c27556c74726120526564273a7b763a5b2723333133423432272c2723464645454534272c2723453534463244272c2723464437413645272c2723464642444237275d2c773a342c62626c3a5b2723453534463244272c27275d7d2c274f6365616e20426c756573273a7b763a5b2723333037334144272c2723373842304532272c2723394343324533272c2723443945444646272c2723303738384439275d2c773a322c62626c3a5b2723443934463330275d7d2c447265616d73636170653a7b763a5b2723453043454641272c2723383841304534272c2723353939314646272c2723464641373934272c2723464638323832272c2723423946444444275d2c773a352c62626c3a5b2723464641373934272c2723464638323832275d7d2c426c6f73736f6d3a7b763a5b2723324137363442272c2723353541353738272c2723463546354439272c2723464643344232272c2723444339333443275d2c773a332c62626c3a5b27272c27272c27275d7d2c4d797374697175653a7b763a5b2723413537414646272c2723433446353030272c2723303343434246272c2723383046464434272c2723303341304646272c2723303436394136272c2723333033333741275d2c773a352c62626c3a5b2723303341304646272c2723433446353030275d7d2c4e6175746963616c3a7b763a5b2723464143393938272c2723454239433434272c2723443934393241272c2723413132343235272c2723333437443935275d2c773a342c62626c3a5b2723443934393241272c2723454239433434275d7d2c526574726f3a7b763a5b2723463445453937272c2723463944373444272c2723454339453433272c2723453236393343272c2723344136303736275d2c773a322c62626c3a5b2723272c2723275d7d2c274f646520746f2056616e20476f6768273a7b763a5b2723324134313834272c2723354138374332272c2723393443304432272c2723454645393836272c2723314232343234275d2c773a332c62626c3a5b2723454645393836275d7d2c274f646520746f204d6f6e647269616e273a7b763a5b2723443242413439272c2723423742384232272c2723313433363735272c2723394532463241272c2723444444444439275d2c773a332c62626c3a5b2723394532463241272c2723313433363735275d7d2c274f646520746f204d6f6e6574273a7b763a5b2723433443374241272c2723333434313437272c2723364138393933272c2723443436453630272c2723443138443734275d2c773a332c62626c3a5b2723443436453630275d7d2c274d69646e6967687420426c7565273a7b763a5b2723303030343231272c2723314243354432275d2c773a322c62626c3a5b2723314243354432275d7d2c4d6f6e6f6368726f6d653a7b763a5b2723463045464546272c2723333733373337275d2c773a327d2c50756e6b61626c653a7b763a5b2723364339314136272c2723443737323437272c2723434245444543272c2723464646304235272c2723333133313331272c2723394243393839272c2723424542454245275d2c773a332c62626c3a5b2723443737323437275d7d2c41706561626c653a7b763a5b2723394139423642272c2723423943424443272c2723463342343638272c2723333936373835272c2723373444344234272c2723393937394130272c2723463246323943275d2c773a332c62626c3a5b2723454430343146275d7d7d2c773d7b536f6c69643a7b763a27736f6c6964272c773a38307d2c5472616e736c7563656e743a7b763a277472616e736c7563656e74272c773a32307d7d2c6d3d7b4c6f773a7b763a7b6d65616e3a31352c7374643a352c666c6f6f723a32307d2c773a36307d2c4d656469756d3a7b763a7b6d65616e3a33302c7374643a352c666c6f6f723a32307d2c773a32307d2c486967683a7b763a7b6d65616e3a34302c7374643a352c666c6f6f723a32307d2c773a31307d7d2c433d7b4e6f6e653a7b763a302c773a38397d2c546869636b3a7b763a312e352c773a31307d2c5468696e3a7b763a312c773a317d7d2c753d7b57686974653a7b763a2772676261283235352c3235352c3235352c2e3829272c773a317d2c426c61636b3a7b763a277267626128302c302c302c2e3629272c773a317d7d2c663d7b53686f72743a7b763a7b6d65616e3a3230302c7374643a3135307d2c773a317d2c4e6f726d616c3a7b763a7b6d65616e3a3430302c7374643a3330307d2c773a317d2c4c6f6e673a7b763a7b6d65616e3a313530302c7374643a3235307d2c773a317d7d2c673d7b5468696e3a7b763a7b6d65616e3a332c7374643a2e317d2c773a32357d2c4e6f726d616c3a7b763a7b6d65616e3a31302c7374643a357d2c773a36307d2c546869636b3a7b763a7b6d65616e3a32302c7374643a357d2c773a31357d7d2c703d7b4e6f726d616c3a7b763a32652d342c773a38357d2c53747261696768743a7b763a31652d362c773a31357d7d2c6b3d7b4e6f726d616c3a7b763a7b6d65616e3a323565332c7374643a323565337d2c773a317d2c4e6f6e653a7b763a7b6d65616e3a302c7374643a307d2c773a317d7d2c4d3d7b274e6f20426f72646572273a7b763a2d32352c773a38357d2c426f726465723a7b763a33352c773a31357d7d3b76617220533d66756e6374696f6e28652c74297b766172206f3d4f626a6563742e6b6579732865292c6c3d5b5d3b666f72286c657420743d303b743c6f2e6c656e6774683b742b2b297b6c6574206e3d655b6f5b745d5d2e773b666f72286c657420653d303b653c6e3b652b2b296c2e70757368286f5b745d297d72657475726e206c5b742e666c6f6f7228742e72616e646f6d28292a6c2e6c656e677468295d7d3b66756e6374696f6e207928652c742c6f2c6c297b6c6574206e3d652e72616e646f6d476175737369616e28322c3130293b76617220723d5b5d2c613d5b5d3b666f722876617220463d303b463c31333b462b2b297b6c6574206c3d6e2b652e72616e646f6d282d6e2f33352c6e2f3335293b725b465d3d742b6c2a652e636f73283336302a462f3133292c615b465d3d6f2b6c2a652e73696e283336302a462f3133297d652e626567696e536861706528293b666f72286c657420743d303b743c722e6c656e6774683b742b2b29652e637572766556657274657828725b745d2c615b745d293b652e656e64536861706528652e434c4f5345297d66756e6374696f6e207828652c742c6f297b6c6574206c3d6f2e72616e646f6d476175737369616e28442c3130293b72657475726e20653c6c7c7c653e6f2e77696474682d6c7c7c743c6c7c7c743e6f2e6865696768742d6c7d66756e6374696f6e204e28652c742c6f297b6c6574206c3d652e72616e646f6d476175737369616e28692e6d65616e2c692e737464292c6e3d652e72616e646f6d476175737369616e28732e6d65616e2c732e737464293b76617220723d5b5d2c463d5b5d3b722e707573682874293b666f72286c657420743d303b743c6c3b742b2b297b6c6574206f3d652e637265617465566563746f7228725b745d2e782b6e2c725b745d2e792b6e293b6966287828725b745d2e782b6e2c725b745d2e792b6e2c6529292d2d742c2d2d6c3b656c73657b462e70757368286f293b76617220763d652e6d617028652e6e6f69736528725b745d2e782a642c725b745d2e792a64292c302c312c302c373230293b6966287828725b745d2e782b652e636f732876292c725b745d2e792b652e73696e2876292c6529292d2d742c2d2d6c3b656c73657b76617220443d652e637265617465566563746f7228725b745d2e782b652e636f732876292c725b745d2e792b652e73696e287629293b722e707573682844297d7d7d666f7228652e626567696e536861706528292c743d303b743c722e6c656e6774683b742b2b297b6c6574206f3d725b745d3b652e766572746578286f2e782c6f2e79297d666f7228743d462e6c656e6774682d313b743e3d303b742d2d297b6c6574206f3d465b745d3b652e766572746578286f2e782c6f2e79297d652e656e64536861706528292c652e7374726f6b652861293b6c657420413d652e636f6c6f72286f293b412e736574416c7068612845292c652e66696c6c2841297d72657475726e7b72656e64657265723a653d3e7b652e73657475703d66756e6374696f6e28297b652e72616e646f6d536565642874292c652e6e6f69736553656564286f293b6c657420783d652e63726561746543616e76617328313530302c353030293b76617220473b666f7228652e616e676c654d6f646528652e44454752454553292c66756e6374696f6e2865297b422e72616e646f6d536565643d742c422e6e6f697365536565643d6f3b6c657420763d5328772c65293b425b2766696c6c2074797065275d3d762c277472616e736c7563656e74273d3d775b765d2e7626262864656c65746520632e4d6f6e6f6368726f6d652c64656c65746520635b274d69646e6967687420426c7565275d2c64656c65746520432e546869636b2c64656c657465206d2e4c6f772c64656c657465206d2e4d656469756d2c683d38302c453d323030293b6c657420623d53284d2c65293b422e626f726465725374796c653d622c28443d4d5b625d2e76293e3026262864656c657465206d2e4c6f772c64656c657465206d2e4d656469756d293b6c657420793d53286d2c65293b422e64656e736974793d792c463d6d5b795d2e763b6c657420783d5328632c65293b422e636f6c6f72733d782c6c3d635b785d2e762c6e3d635b785d2e62626c2c274d69646e6967687420426c7565273d3d7826262864656c65746520752e426c61636b2c64656c65746520432e4e6f6e652c64656c65746520432e546869636b292c274d6f6e6f6368726f6d65273d3d7826262864656c65746520752e57686974652c64656c65746520432e4e6f6e652c64656c65746520432e546869636b293b6c6574204e3d5328432c65293b422e7374726f6b65546869636b6e6573733d4e2c723d435b4e5d2e763b6c657420473d5328752c65293b422e7374726f6b65436f6c6f723d472c613d755b475d2e763b6c657420543d5328662c65293b422e63757276654c656e6774683d542c693d665b545d2e763b6c6574204c3d5328672c65293b422e637572766557696474683d4c2c733d675b4c5d2e763b6c6574204f3d5328702c65293b422e6375727665526174653d4f2c643d705b4f5d2e763b6c657420523d53286b2c65293b422e7465787475726544656e736974793d522c413d6b5b525d2e767d2865293b6e756c6c3d3d473b297b6c657420743d6c5b652e666c6f6f7228652e72616e646f6d28292a6c2e6c656e677468295d3b6e756c6c213d6e26266e2e696e636c756465732874297c7c28473d74297d652e6261636b67726f756e642847292c6c3d6c2e66696c74657228653d3e65213d47292c652e7374726f6b655765696768742872293b6c657420543d652e666c6f6f7228652e6d617828652e72616e646f6d476175737369616e28462e6d65616e2c462e737464292c462e666c6f6f7229293b666f7228766172204c3d652e77696474682f542c4f3d443b4f3c652e77696474682d443b4f2b3d4c29666f722876617220523d443b523c652e6865696768742d443b522b3d4c29696628652e666c6f6f72283130302a652e72616e646f6d2829293c3d68297b76617220553d652e637265617465566563746f72284f2b652e72616e646f6d282d31302c3130292c522b652e72616e646f6d282d31302c313029293b4e28652c552c6c5b652e666c6f6f7228652e72616e646f6d28292a6c2e6c656e677468295d297d656c736520652e72616e646f6d28292c652e77696474682c652e72616e646f6d28292c652e6865696768742c7928652c4f2b652e72616e646f6d476175737369616e2832302c3230292c522b652e72616e646f6d2832302c3230292c6c5b652e666c6f6f7228652e72616e646f6d28292a6c2e6c656e677468295d293b763d652e72616e646f6d476175737369616e28412e6d65616e2c412e737464292c66756e6374696f6e28652c74297b6c6574206f3d652e666c6f6f7228652e72616e646f6d2835302c393029292c6c3d652e636f6c6f722832302c32302c32302c6f293b652e6e6f5374726f6b6528292c652e66696c6c286c293b666f72286c6574206f3d303b6f3c743b6f2b2b297b6c657420743d652e72616e646f6d28292a652e77696474682c6f3d652e72616e646f6d28292a652e6865696768742c6c3d652e72616e646f6d28302c312e35293b652e656c6c6970736528742c6f2c6c297d7d28652c76292c622e6461746155726c3d782e63616e7661732e746f4461746155524c28297d2c652e647261773d66756e6374696f6e28297b652e6e6f4c6f6f7028297d7d2c70726f706572746965733a422c6461746155726c3a627d7d00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c10000000000000000000000000000000000000000000000000000000000000180000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000000000000000000000000001bc16d674ec80000aa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af44500000000000000000000000000000000000000000000000000000000000000174d656368616e697a6564204162737472616374696f6e7300000000000000000000000000000000000000000000000000000000000000000000000000000000024d41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b684265496f56715473705a416e62347a4a62794e464454304b524433646c52336967467843314d65554841000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102325760003560e01c806301ffc9a71461027757806304da5304146102ad57806306fdde03146102cf57806307ba3196146102f1578063081812fc14610306578063095ea7b31461033357806314d53c25146103535780631c8a173914610380578063231871d6146103a057806323b872dd146103b5578063248a9ca3146103d5578063282c51f3146103f55780632d2b26ee1461040a5780632f2ff15d1461042a57806336568abe1461044a578063374145ce1461046a57806342842e0e1461048a57806342966c68146104aa5780634417d216146104ca5780634f638a40146104df578063506eb3f8146104ff57806355f804b3146105145780635b2906d0146105345780636352211e146105495780636602529214610569578063684297de1461057e57806370a0823114610593578063715018a6146105b357806375794a3c146105c85780638da5cb5b146105dd5780638dc654a2146105f257806391d148541461060757806394985ddd1461062757806395d89b41146106475780639e8ed6f71461065c578063a0ef91df14610671578063a217fddf14610686578063a22cb4651461069b578063b07fe3a1146106bb578063b88d4fde146106d0578063c8321c78146106f0578063c87b56dd14610710578063cd7c032614610730578063cf76a15314610745578063d53913931461075a578063d547741f1461076f578063e985e9c51461078f578063f2bfb811146107af578063f2fde38b146107cf57610272565b36610272577ffc0190751e68e3a764092e8161dc292f90c0e10e38ddf16a6b42670667bcac47343360405161026892919061331d565b60405180910390a1005b600080fd5b34801561028357600080fd5b50610297610292366004612957565b6107ef565b6040516102a49190612cee565b60405180910390f35b3480156102b957600080fd5b506102cd6102c83660046129ab565b610852565b005b3480156102db57600080fd5b506102e46108cd565b6040516102a49190612d26565b3480156102fd57600080fd5b506102e461095f565b34801561031257600080fd5b506103266103213660046128fa565b6109ed565b6040516102a49190612c54565b34801561033f57600080fd5b506102cd61034e3660046128b3565b610a30565b34801561035f57600080fd5b5061037361036e3660046128fa565b610ac3565b6040516102a49190612cf9565b34801561038c57600080fd5b506102cd61039b3660046129ab565b610ad5565b3480156103ac57600080fd5b50610373610b42565b3480156103c157600080fd5b506102cd6103d03660046127ca565b610b48565b3480156103e157600080fd5b506103736103f03660046128fa565b610b80565b34801561040157600080fd5b50610373610b95565b34801561041657600080fd5b506102cd610425366004612912565b610ba7565b34801561043657600080fd5b506102cd610445366004612912565b610c86565b34801561045657600080fd5b506102cd610465366004612912565b610ca5565b34801561047657600080fd5b506102e46104853660046128fa565b610ceb565b34801561049657600080fd5b506102cd6104a53660046127ca565b610d16565b3480156104b657600080fd5b506102cd6104c53660046128fa565b610d31565b3480156104d657600080fd5b50610373610d55565b3480156104eb57600080fd5b506102cd6104fa366004612a61565b610ec3565b34801561050b57600080fd5b506102e4610fd3565b34801561052057600080fd5b506102cd61052f366004612a17565b610fe0565b34801561054057600080fd5b50610297611054565b34801561055557600080fd5b506103266105643660046128fa565b61105d565b34801561057557600080fd5b506102cd611092565b34801561058a57600080fd5b506102e46110dd565b34801561059f57600080fd5b506103736105ae366004612776565b6110ea565b3480156105bf57600080fd5b506102cd61112e565b3480156105d457600080fd5b50610373611179565b3480156105e957600080fd5b5061032661117f565b3480156105fe57600080fd5b506102cd61118e565b34801561061357600080fd5b50610297610622366004612912565b6112fe565b34801561063357600080fd5b506102cd610642366004612936565b611329565b34801561065357600080fd5b506102e461137b565b34801561066857600080fd5b5061037361138a565b34801561067d57600080fd5b506102cd611390565b34801561069257600080fd5b5061037361144e565b3480156106a757600080fd5b506102cd6106b6366004612886565b611453565b3480156106c757600080fd5b506102cd611465565b3480156106dc57600080fd5b506102cd6106eb36600461280a565b6114de565b3480156106fc57600080fd5b506102cd61070b3660046129ab565b611517565b34801561071c57600080fd5b506102e461072b3660046128fa565b611584565b34801561073c57600080fd5b506103266116ac565b34801561075157600080fd5b506102e46116bb565b34801561076657600080fd5b506103736116c8565b34801561077b57600080fd5b506102cd61078a366004612912565b6116da565b34801561079b57600080fd5b506102976107aa366004612792565b6116f9565b3480156107bb57600080fd5b506103736107ca3660046128fa565b6117ad565b3480156107db57600080fd5b506102cd6107ea366004612776565b6117ce565b60006001600160e01b031982166380ac58cd60e01b148061082057506001600160e01b03198216635b5e139f60e01b145b8061083b57506001600160e01b03198216637965db0b60e01b145b8061084a575061084a8261183c565b90505b919050565b61085a61187c565b6001600160a01b031661086b61117f565b6001600160a01b03161461089a5760405162461bcd60e51b815260040161089190613159565b60405180910390fd5b600e5460ff166108bc5760405162461bcd60e51b815260040161089190613087565b6108c8600a8383612546565b505050565b6060600280546108dc90613411565b80601f016020809104026020016040519081016040528092919081815260200182805461090890613411565b80156109555780601f1061092a57610100808354040283529160200191610955565b820191906000526020600020905b81548152906001019060200180831161093857829003601f168201915b5050505050905090565b600a805461096c90613411565b80601f016020809104026020016040519081016040528092919081815260200182805461099890613411565b80156109e55780601f106109ba576101008083540402835291602001916109e5565b820191906000526020600020905b8154815290600101906020018083116109c857829003601f168201915b505050505081565b60006109f882611880565b610a145760405162461bcd60e51b81526004016108919061310d565b506000908152600660205260409020546001600160a01b031690565b6000610a3b8261105d565b9050806001600160a01b0316836001600160a01b03161415610a6f5760405162461bcd60e51b81526004016108919061320e565b806001600160a01b0316610a8161187c565b6001600160a01b03161480610a9d5750610a9d816107aa61187c565b610ab95760405162461bcd60e51b815260040161089190612f9c565b6108c8838361189d565b60166020526000908152604090205481565b610add61187c565b6001600160a01b0316610aee61117f565b6001600160a01b031614610b145760405162461bcd60e51b815260040161089190613159565b600e5460ff16610b365760405162461bcd60e51b815260040161089190613087565b6108c8600d8383612546565b60105490565b610b59610b5361187c565b8261190b565b610b755760405162461bcd60e51b81526004016108919061324f565b6108c8838383611988565b60009081526020819052604090206001015490565b6000805160206134f783398151915281565b600080516020613517833981519152610bc781610bc261187c565b611aa3565b60005b83811015610c8057610bde83600f54611b07565b600f5460145433424340604051602001610bfc959493929190613334565b60408051601f198184030181528282528051602091820120600f8054600090815260169093529290912055547f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe91610c55918691612ca5565b60405180910390a1600f54610c6b906001611b21565b600f5580610c788161344c565b915050610bca565b50505050565b610c8f82610b80565b610c9b81610bc261187c565b6108c88383611b34565b610cad61187c565b6001600160a01b0316816001600160a01b031614610cdd5760405162461bcd60e51b8152600401610891906132ce565b610ce78282611bb9565b5050565b60118181548110610cfb57600080fd5b90600052602060002001600091509050805461096c90613411565b6108c8838383604051806020016040528060008152506114de565b6000805160206134f7833981519152610d4c81610bc261187c565b610ce782611c3c565b6000610d5f61187c565b6001600160a01b0316610d7061117f565b6001600160a01b031614610d965760405162461bcd60e51b815260040161089190613159565b600e5460ff16610db85760405162461bcd60e51b815260040161089190613087565b6013546040516370a0823160e01b81526001600160a01b037f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca16906370a0823190610e07903090600401612c54565b60206040518083038186803b158015610e1f57600080fd5b505afa158015610e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e579190612a49565b1015610e755760405162461bcd60e51b8152600401610891906130af565b6000610e85601254601354611cd1565b90507f0a2d241dbb61e3eff8f8c6dd39c403577e294dd102fe1b2880ede8145656b1f681604051610eb69190612cf9565b60405180910390a1905090565b610ecb61187c565b6001600160a01b0316610edc61117f565b6001600160a01b031614610f025760405162461bcd60e51b815260040161089190613159565b60105415610f635760108054839190610f1d906001906133b7565b81548110610f3b57634e487b7160e01b600052603260045260246000fd5b906000526020600020015410610f635760405162461bcd60e51b815260040161089190612ee0565b6010805460018181019092557f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720183905560118054918201815560005281516108c8917f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68019060208401906125ca565b600c805461096c90613411565b610fe861187c565b6001600160a01b0316610ff961117f565b6001600160a01b03161461101f5760405162461bcd60e51b815260040161089190613159565b600e5460ff166110415760405162461bcd60e51b815260040161089190613087565b8051610ce790600b9060208401906125ca565b600e5460ff1681565b6000818152600460205260408120546001600160a01b03168061084a5760405162461bcd60e51b81526004016108919061303e565b61109a61187c565b6001600160a01b03166110ab61117f565b6001600160a01b0316146110d15760405162461bcd60e51b815260040161089190613159565b600e805460ff19169055565b600d805461096c90613411565b60006001600160a01b0382166111125760405162461bcd60e51b815260040161089190612ff4565b506001600160a01b031660009081526005602052604090205490565b61113661187c565b6001600160a01b031661114761117f565b6001600160a01b03161461116d5760405162461bcd60e51b815260040161089190613159565b6111776000611e0c565b565b600f5481565b6001546001600160a01b031690565b61119661187c565b6001600160a01b03166111a761117f565b6001600160a01b0316146111cd5760405162461bcd60e51b815260040161089190613159565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca169063a9059cbb90339083906370a0823190611223903090600401612c54565b60206040518083038186803b15801561123b57600080fd5b505afa15801561124f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112739190612a49565b6040518363ffffffff1660e01b8152600401611290929190612ca5565b602060405180830381600087803b1580156112aa57600080fd5b505af11580156112be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e291906128de565b6111775760405162461bcd60e51b8152600401610891906132a0565b6000828152602081815260408083206001600160a01b038516845290915290205460ff165b92915050565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795216146113715760405162461bcd60e51b8152600401610891906131d7565b610ce78282611e5e565b6060600380546108dc90613411565b60145481565b61139861187c565b6001600160a01b03166113a961117f565b6001600160a01b0316146113cf5760405162461bcd60e51b815260040161089190613159565b6000336001600160a01b0316476040516113e890612be2565b60006040518083038185875af1925050503d8060008114611425576040519150601f19603f3d011682016040523d82523d6000602084013e61142a565b606091505b505090508061144b5760405162461bcd60e51b815260040161089190612f6f565b50565b600081565b610ce761145e61187c565b8383611e9f565b61146d61187c565b6001600160a01b031661147e61117f565b6001600160a01b0316146114a45760405162461bcd60e51b815260040161089190613159565b600e5460ff166114c65760405162461bcd60e51b815260040161089190613087565b6114d26010600061263e565b6111776011600061265c565b6114ef6114e961187c565b8361190b565b61150b5760405162461bcd60e51b81526004016108919061324f565b610c8084848484611f42565b61151f61187c565b6001600160a01b031661153061117f565b6001600160a01b0316146115565760405162461bcd60e51b815260040161089190613159565b600e5460ff166115785760405162461bcd60e51b815260040161089190613087565b6108c8600c8383612546565b606061158f82611880565b6115ab5760405162461bcd60e51b815260040161089190612d39565b60008060005b60105481101561160c57601081815481106115dc57634e487b7160e01b600052603260045260246000fd5b90600052602060002001548510156115fa578092506001915061160c565b806116048161344c565b9150506115b1565b508061164c5761161a611f75565b61162385611f84565b604051602001611634929190612b77565b6040516020818303038152906040529250505061084d565b600d6011838154811061166f57634e487b7160e01b600052603260045260246000fd5b9060005260206000200161168286611f84565b60405160200161169493929190612ba6565b60405160208183030381529060405292505050919050565b6009546001600160a01b031681565b600b805461096c90613411565b60008051602061351783398151915281565b6116e382610b80565b6116ef81610bc261187c565b6108c88383611bb9565b60095460405163c455279160e01b81526000916001600160a01b039081169190841690829063c455279190611732908890600401612c54565b60206040518083038186803b15801561174a57600080fd5b505afa15801561175e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611782919061298f565b6001600160a01b0316141561179b576001915050611323565b6117a5848461209e565b949350505050565b601081815481106117bd57600080fd5b600091825260209091200154905081565b6117d661187c565b6001600160a01b03166117e761117f565b6001600160a01b03161461180d5760405162461bcd60e51b815260040161089190613159565b6001600160a01b0381166118335760405162461bcd60e51b815260040161089190612ded565b61144b81611e0c565b60006001600160e01b031982166380ac58cd60e01b148061186d57506001600160e01b03198216635b5e139f60e01b145b8061084a575061084a826120cc565b3390565b6000908152600460205260409020546001600160a01b0316151590565b600081815260066020526040902080546001600160a01b0319166001600160a01b03841690811790915581906118d28261105d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061191682611880565b6119325760405162461bcd60e51b815260040161089190612f23565b600061193d8361105d565b9050806001600160a01b0316846001600160a01b031614806119785750836001600160a01b031661196d846109ed565b6001600160a01b0316145b806117a557506117a581856116f9565b826001600160a01b031661199b8261105d565b6001600160a01b0316146119c15760405162461bcd60e51b81526004016108919061318e565b6001600160a01b0382166119e75760405162461bcd60e51b815260040161089190612e69565b6119f28383836108c8565b6119fd60008261189d565b6001600160a01b0383166000908152600560205260408120805460019290611a269084906133b7565b90915550506001600160a01b0382166000908152600560205260408120805460019290611a5490849061336c565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b03868116918217909255915184939187169160008051602061353783398151915291a4505050565b611aad82826112fe565b610ce757611ac5816001600160a01b031660146120f1565b611ad08360206120f1565b604051602001611ae1929190612be5565b60408051601f198184030181529082905262461bcd60e51b825261089191600401612d26565b610ce78282604051806020016040528060008152506122a2565b6000611b2d828461336c565b9392505050565b611b3e82826112fe565b610ce7576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055611b7561187c565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b611bc382826112fe565b15610ce7576000828152602081815260408083206001600160a01b03851684529091529020805460ff19169055611bf861187c565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000611c478261105d565b9050611c55816000846108c8565b611c6060008361189d565b6001600160a01b0381166000908152600560205260408120805460019290611c899084906133b7565b909155505060008281526004602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020613537833981519152908390a45050565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795284866000604051602001611d38929190612b69565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611d6593929190612cbe565b602060405180830381600087803b158015611d7f57600080fd5b505af1158015611d93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db791906128de565b50600083815260086020526040812054611dd6908590839030906122d5565b600085815260086020526040902054909150611df390600161336c565b6000858152600860205260409020556117a5848261230f565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60148190556040517f201bfd6a460f81d26c819af2ca157f01e3c82f32d4d322fa1715cb4a394203c590611e93908490612cf9565b60405180910390a15050565b816001600160a01b0316836001600160a01b03161415611ed15760405162461bcd60e51b815260040161089190612ead565b6001600160a01b0383811660008181526007602090815260408083209487168084529490915290819020805460ff1916851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190611f35908590612cee565b60405180910390a3505050565b611f4d848484611988565b611f5984848484612342565b610c805760405162461bcd60e51b815260040161089190612d9b565b6060600b80546108dc90613411565b606081611fa957506040805180820190915260018152600360fc1b602082015261084d565b8160005b8115611fd35780611fbd8161344c565b9150611fcc9050600a83613384565b9150611fad565b6000816001600160401b03811115611ffb57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612025576020820181803683370190505b5090505b84156117a55761203a6001836133b7565b9150612047600a86613467565b61205290603061336c565b60f81b81838151811061207557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612097600a86613384565b9450612029565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061084a575061084a8261245a565b60606000612100836002613398565b61210b90600261336c565b6001600160401b0381111561213057634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561215a576020820181803683370190505b509050600360fc1b8160008151811061218357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106121c057634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006121e4846002613398565b6121ef90600161336c565b90505b6001811115612283576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061223157634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061225557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361227c816133fa565b90506121f2565b508315611b2d5760405162461bcd60e51b815260040161089190612d66565b6122ac8383612473565b6122b96000848484612342565b6108c85760405162461bcd60e51b815260040161089190612d9b565b6000848484846040516020016122ee9493929190612d02565b60408051601f19818403018152919052805160209091012095945050505050565b60008282604051602001612324929190612b69565b60405160208183030381529060405280519060200120905092915050565b6000612356846001600160a01b0316612540565b1561245257836001600160a01b031663150b7a0261237261187c565b8786866040518563ffffffff1660e01b81526004016123949493929190612c68565b602060405180830381600087803b1580156123ae57600080fd5b505af19250505080156123de575060408051601f3d908101601f191682019092526123db91810190612973565b60015b612438573d80801561240c576040519150601f19603f3d011682016040523d82523d6000602084013e612411565b606091505b5080516124305760405162461bcd60e51b815260040161089190612d9b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506117a5565b5060016117a5565b6001600160e01b031981166301ffc9a760e01b14919050565b6001600160a01b0382166124995760405162461bcd60e51b8152600401610891906130d8565b6124a281611880565b156124bf5760405162461bcd60e51b815260040161089190612e33565b6124cb600083836108c8565b6001600160a01b03821660009081526005602052604081208054600192906124f490849061336c565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020613537833981519152908290a45050565b3b151590565b82805461255290613411565b90600052602060002090601f01602090048101928261257457600085556125ba565b82601f1061258d5782800160ff198235161785556125ba565b828001600101855582156125ba579182015b828111156125ba57823582559160200191906001019061259f565b506125c692915061267a565b5090565b8280546125d690613411565b90600052602060002090601f0160209004810192826125f857600085556125ba565b82601f1061261157805160ff19168380011785556125ba565b828001600101855582156125ba579182015b828111156125ba578251825591602001919060010190612623565b508054600082559060005260206000209081019061144b919061267a565b508054600082559060005260206000209081019061144b919061268f565b5b808211156125c6576000815560010161267b565b808211156125c65760006126a382826126ac565b5060010161268f565b5080546126b890613411565b6000825580601f106126ca575061144b565b601f01602090049060005260206000209081019061144b919061267a565b60006001600160401b0380841115612702576127026134a7565b604051601f8501601f191681016020018281118282101715612726576127266134a7565b60405284815291508183850186101561273e57600080fd5b8484602083013760006020868301015250509392505050565b600082601f830112612767578081fd5b611b2d838335602085016126e8565b600060208284031215612787578081fd5b8135611b2d816134bd565b600080604083850312156127a4578081fd5b82356127af816134bd565b915060208301356127bf816134bd565b809150509250929050565b6000806000606084860312156127de578081fd5b83356127e9816134bd565b925060208401356127f9816134bd565b929592945050506040919091013590565b6000806000806080858703121561281f578081fd5b843561282a816134bd565b9350602085013561283a816134bd565b92506040850135915060608501356001600160401b0381111561285b578182fd5b8501601f8101871361286b578182fd5b61287a878235602084016126e8565b91505092959194509250565b60008060408385031215612898578182fd5b82356128a3816134bd565b915060208301356127bf816134d2565b600080604083850312156128c5578182fd5b82356128d0816134bd565b946020939093013593505050565b6000602082840312156128ef578081fd5b8151611b2d816134d2565b60006020828403121561290b578081fd5b5035919050565b60008060408385031215612924578182fd5b8235915060208301356127bf816134bd565b60008060408385031215612948578182fd5b50508035926020909101359150565b600060208284031215612968578081fd5b8135611b2d816134e0565b600060208284031215612984578081fd5b8151611b2d816134e0565b6000602082840312156129a0578081fd5b8151611b2d816134bd565b600080602083850312156129bd578182fd5b82356001600160401b03808211156129d3578384fd5b818501915085601f8301126129e6578384fd5b8135818111156129f4578485fd5b866020828501011115612a05578485fd5b60209290920196919550909350505050565b600060208284031215612a28578081fd5b81356001600160401b03811115612a3d578182fd5b6117a584828501612757565b600060208284031215612a5a578081fd5b5051919050565b60008060408385031215612a73578182fd5b8235915060208301356001600160401b03811115612a8f578182fd5b612a9b85828601612757565b9150509250929050565b60008151808452612abd8160208601602086016133ce565b601f01601f19169290920160200192915050565b805460009060028104600180831680612aeb57607f831692505b6020808410821415612b0b57634e487b7160e01b86526022600452602486fd5b818015612b1f5760018114612b3057612b5d565b60ff19861689528489019650612b5d565b612b3988613360565b60005b86811015612b555781548b820152908501908301612b3c565b505084890196505b50505050505092915050565b918252602082015260400190565b60008351612b898184602088016133ce565b835190830190612b9d8183602088016133ce565b01949350505050565b6000612bbb612bb58387612ad1565b85612ad1565b602f60f81b81528351612bd58160018401602088016133ce565b0160010195945050505050565b90565b600076020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b82528351612c178160178501602088016133ce565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612c488160288401602088016133ce565b01602801949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612c9b90830184612aa5565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038516825283602083015260606040830152612ce56060830184612aa5565b95945050505050565b901515815260200190565b90815260200190565b93845260208401929092526001600160a01b03166040830152606082015260800190565b600060208252611b2d6020830184612aa5565b6020808252601390820152721513d2d153881113d154d389d50811561254d5606a1b604082015260600190565b6020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b604082015260600190565b60208082526023908201527f42415443482049442053484f554c44204558434545442050524556494f5553206040820152624f4e4560e81b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526013908201527211551208151c985b9cd9995c8819985a5b1959606a1b604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776040820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252600e908201526d4e4f54204d4f4449464941424c4560901b604082015260600190565b6020808252600f908201526e4e4f5420454e4f554748204c494e4b60881b604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252601f908201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c00604082015260600190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526014908201527313125392c8151c985b9cd9995c8819985a5b195960621b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b9182526001600160a01b0316602082015260400190565b94855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b60009081526020902090565b6000821982111561337f5761337f61347b565b500190565b60008261339357613393613491565b500490565b60008160001904831182151516156133b2576133b261347b565b500290565b6000828210156133c9576133c961347b565b500390565b60005b838110156133e95781810151838201526020016133d1565b83811115610c805750506000910152565b6000816134095761340961347b565b506000190190565b60028104600182168061342557607f821691505b6020821081141561344657634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156134605761346061347b565b5060010190565b60008261347657613476613491565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461144b57600080fd5b801515811461144b57600080fd5b6001600160e01b03198116811461144b57600080fdfe3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8489f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c420e3c344454a68d64da6eaabb0a3c9902d7cdcf884ca7519271eec4d79548164736f6c63430008000033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c10000000000000000000000000000000000000000000000000000000000000180000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000000000000000000000000001bc16d674ec80000aa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af44500000000000000000000000000000000000000000000000000000000000000174d656368616e697a6564204162737472616374696f6e7300000000000000000000000000000000000000000000000000000000000000000000000000000000024d41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b684265496f56715473705a416e62347a4a62794e464454304b524433646c52336967467843314d65554841000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Mechanized Abstractions
Arg [1] : _symbol (string): MA
Arg [2] : _proxyRegistryAddress (address): 0xa5409ec958C83C3f309868babACA7c86DCB077c1
Arg [3] : _p5ScriptArweaveAddress (string): hBeIoVqTspZAnb4zJbyNFDT0KRD3dlR3igFxC1MeUHA
Arg [4] : _vrfCoordinator (address): 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952
Arg [5] : _linkTokenAddress (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [6] : _vrfFee (uint256): 2000000000000000000
Arg [7] : _keyHash (bytes32): 0xaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445
-----Encoded View---------------
15 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [4] : 000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952
Arg [5] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [6] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [7] : aa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000017
Arg [9] : 4d656368616e697a6564204162737472616374696f6e73000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [11] : 4d41000000000000000000000000000000000000000000000000000000000000
Arg [12] : 000000000000000000000000000000000000000000000000000000000000002b
Arg [13] : 684265496f56715473705a416e62347a4a62794e464454304b524433646c5233
Arg [14] : 6967467843314d65554841000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.