0x75de…6127

All memos sent from and to 0x75de…6127.

FacetSwapV1Router: EXCESSIVE_INP`DUniswapV2Router: EXCESSIVE_INPUT`DFee cannot be greater than 100%a$7V[Qa iV[`@QbFFacetSwapV1Router: INSUFFICIENT_`DFacetSwapV1Library: INVALID_PATH`DMax path length exceededRouter WETH balance decreasedMust have WETH as either first o`DRpCannot self trade`xFacetSwapV1Router: EXPIREDFacetSwapV1Router: INSUFFICIENT_`DFacetSwapV1Router: INSUFFICIENT_`DFacetSwapV1Library: ZERO_ADDRESS`DFacetSwapV1Library: IDENTICAL_AD`DTransferHelper::transferFrom: tr`DFacetSwapV1Library: INSUFFICIENT
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x1673540243e793b0e77c038d4a88448eff524dce","function":"upgrade","args":{"newHash":"0xa46f3d0539f8556dc2f86b63e68249db6c1db193da387d780aaded983f4c7ae4","newSource":"pragma(:rubidity, \"1.0.0\")\ncontract(:ERC20, abstract: true) {\n event(:Transfer, { from: :address, to: :address, amount: :uint256 })\n event(:Approval, { owner: :address, spender: :address, amount: :uint256 })\n string(:public, :name)\n string(:public, :symbol)\n uint8(:public, :decimals)\n uint256(:public, :totalSupply)\n mapping(({ address: :uint256 }), :public, :balanceOf)\n mapping(({ address: mapping(address: :uint256) }), :public, :allowance)\n constructor(name: :string, symbol: :string, decimals: :uint8) {\n s.name=name\n s.symbol=symbol\n s.decimals=decimals\n }\n function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n s.allowance[msg.sender][spender] = amount\n emit(:Approval, owner: msg.sender, spender: spender, amount: amount)\n return true\n }\n function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n require(s.balanceOf[msg.sender] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[msg.sender] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: msg.sender, to: to, amount: amount)\n return true\n }\n function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n allowed = s.allowance[from][msg.sender]\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n require(allowed \u003e= amount, \"Insufficient allowance\")\n s.allowance[from][msg.sender] = allowed - amount\n s.balanceOf[from] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: from, to: to, amount: amount)\n return true\n }\n function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {\n s.totalSupply += amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: address(0), to: to, amount: amount)\n }\n function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[from] -= amount\n s.totalSupply -= amount\n emit(:Transfer, from: from, to: address(0), amount: amount)\n }\n}\ncontract(:FacetBuddy) {\n event(:CallOnBehalfOfUser, { onBehalfOf: :address, addressToCall: :address, calldata: :string, initialAmount: :uint256, finalAmount: :uint256, resultSuccess: :bool, resultData: :string })\n address(:public, :factory)\n address(:public, :erc20Bridge)\n address(:public, :forUser)\n bool(:locked)\n constructor(erc20Bridge: :address, forUser: :address) {\n s.factory=msg.sender\n s.erc20Bridge=erc20Bridge\n s.forUser=forUser\n }\n function(:_makeCall, { addressToCall: :address, calldata: :string, revertOnFailure: :bool }, :internal) {\n require(addressToCall != address(this), \"Cannot call self\")\n require(!s.locked, \"No reentrancy allowed\")\n s.locked=true\n initialBalance = _balance\n _approve(addressToCall, initialBalance)\n (success, data) = addressToCall.call(calldata)\n require(success || !revertOnFailure, \"Call failed: (#{calldata})\")\n _approve(addressToCall, 0)\n finalBalance = _balance\n if finalBalance \u003e 0\n _transfer(s.forUser, finalBalance)\n end\n s.locked=false\n emit(:CallOnBehalfOfUser, onBehalfOf: s.forUser, addressToCall: addressToCall, calldata: calldata, initialAmount: initialBalance, finalAmount: finalBalance, resultSuccess: success, resultData: data)\n }\n function(:callForUser, { amountToSpend: :uint256, addressToCall: :address, calldata: :string }, :public) {\n require(msg.sender == s.forUser || msg.sender == s.factory, \"Only the user or factory can callForUser\")\n ERC20(s.erc20Bridge).transferFrom(s.forUser, address(this), amountToSpend)\n _makeCall(addressToCall, calldata, true)\n }\n function(:callFromBridge, { addressToCall: :address, calldata: :string }, :public) {\n require(msg.sender == s.erc20Bridge, \"Only the bridge can callFromBridge\")\n _makeCall(addressToCall, calldata, false)\n }\n function(:_balance, :internal, :view, returns: :uint256) {\n ERC20(s.erc20Bridge).balanceOf(address(this))\n }\n function(:_approve, { spender: :address, amount: :uint256 }, :internal, returns: :bool) {\n ERC20(s.erc20Bridge).approve(spender, amount)\n }\n function(:_transfer, { to: :address, amount: :uint256 }, :internal, returns: :bool) {\n ERC20(s.erc20Bridge).transfer(to, amount)\n }\n}\ncontract(:Upgradeable, abstract: true) {\n address(:public, :upgradeAdmin)\n event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })\n event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })\n constructor(upgradeAdmin: :address) {\n s.upgradeAdmin=upgradeAdmin\n }\n function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n s.upgradeAdmin=newUpgradeAdmin\n emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)\n }\n function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {\n upgrade(newHash: newHash, newSource: newSource)\n (success, data) = address(this).call(migrationCalldata)\n require(success, \"Migration failed\")\n }\n function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {\n currentHash = this.currentInitCodeHash\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n this.upgradeImplementation(newHash, newSource)\n emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)\n }\n}\ncontract(:FacetBuddyFactory, is: [:Upgradeable], upgradeable: true) {\n event(:BuddyCreated, { forUser: :address, buddy: :address })\n address(:public, :erc20Bridge)\n mapping(({ address: :address }), :public, :buddyForUser)\n mapping(({ address: :address }), :public, :userForBuddy)\n constructor(erc20Bridge: :address) {\n require(erc20Bridge != address(0), \"Invalid smart contract\")\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n s.erc20Bridge=erc20Bridge\n }\n function(:findOrCreateBuddy, { forUser: :address }, :public, returns: :address) {\n existingBuddy = s.buddyForUser[forUser]\n if existingBuddy != address(0)\n return existingBuddy\n end\n salt = keccak256(abi.encodePacked(forUser))\n buddy = new(FacetBuddy(s.erc20Bridge, forUser, { salt: salt }))\n require(s.userForBuddy[buddy] == address(0), \"Buddy already exists for user\")\n s.buddyForUser[forUser] = buddy\n s.userForBuddy[buddy] = forUser\n emit(:BuddyCreated, forUser: forUser, buddy: buddy)\n return buddy\n }\n function(:callBuddyForUser, { amountToSpend: :uint256, addressToCall: :address, calldata: :string }, :public) {\n buddy = findOrCreateBuddy(msg.sender)\n FacetBuddy(buddy).callForUser(amountToSpend: amountToSpend, addressToCall: addressToCall, calldata: calldata)\n }\n function(:predictBuddyAddress, { forUser: :address }, :public, :view, returns: :address) {\n return create2_address(salt: keccak256(abi.encodePacked(forUser)), deployer: address(this), contract_type: \"FacetBuddy\")\n }\n}\ncontract(:Ownable, abstract: true) {\n address(:public, :owner)\n event(:OwnershipTransferred, { previousOwner: :address, newOwner: :address })\n constructor(owner: :address) {\n s.owner=owner\n }\n function(:transferOwnership, { newOwner: :address }, :public) {\n onlyOwner!\n previousOwner = s.owner\n s.owner=newOwner\n emit(:OwnershipTransferred, previousOwner: previousOwner, newOwner: newOwner)\n }\n function(:onlyOwner!, :internal) {\n require(msg.sender == s.owner, \"msg.sender is not the owner\")\n }\n}\ncontract(:Pausable, abstract: true) {\n bool(:public, :paused)\n event(:Paused, { account: :address })\n event(:Unpaused, { account: :address })\n constructor(initialPauseState: :bool) {\n s.paused=initialPauseState\n }\n function(:_pause, :internal) {\n s.paused=true\n emit(:Paused, account: msg.sender)\n }\n function(:_unpause, :internal) {\n s.paused=false\n emit(:Unpaused, account: msg.sender)\n }\n function(:whenPaused!, :internal) {\n require(s.paused, \"Contract is not paused\")\n }\n function(:whenNotPaused!, :internal) {\n require(!s.paused, \"Contract is paused\")\n }\n}\ncontract(:EtherBridge04, is: [:ERC20, :Upgradeable, :Ownable, :Pausable], upgradeable: true) {\n event(:BridgedIn, { to: :address, amount: :uint256 })\n event(:InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 })\n event(:WithdrawalComplete, { to: :address, amount: :uint256, withdrawalId: :bytes32 })\n address(:public, :trustedSmartContract)\n address(:public, :facetBuddyFactory)\n mapping(({ bytes32: :uint256 }), :public, :withdrawalIdAmount)\n mapping(({ address: :bytes32 }), :public, :userWithdrawalId)\n constructor(name: :string, symbol: :string, trustedSmartContract: :address) {\n require(trustedSmartContract != address(0), \"Invalid smart contract\")\n self.ERC20.constructor(name: name, symbol: symbol, decimals: 18)\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n self.Ownable.constructor(owner: msg.sender)\n s.trustedSmartContract=trustedSmartContract\n }\n function(:setFacetBuddyFactory, { facetBuddyFactory: :address }, :public) {\n onlyOwner!\n s.facetBuddyFactory=facetBuddyFactory\n nil\n }\n function(:bridgeIn, { to: :address, amount: :uint256 }, :public) {\n require(msg.sender == s.trustedSmartContract, \"Only the trusted smart contract can bridge in tokens\")\n _mint(to: to, amount: amount)\n emit(:BridgedIn, to: to, amount: amount)\n }\n function(:bridgeAndCall, { to: :address, amount: :uint256, addressToCall: :address, base64Calldata: :string }, :public) {\n if s.facetBuddyFactory == address(0)\n return bridgeIn(to: to, amount: amount)\n end\n buddy = FacetBuddyFactory(s.facetBuddyFactory).findOrCreateBuddy(to)\n bridgeIn(to: buddy, amount: amount)\n FacetBuddy(buddy).callFromBridge(addressToCall: addressToCall, calldata: base64Calldata.base64Decode)\n }\n function(:predictBuddyAddress, { forUser: :address }, :public, :view, returns: :address) {\n return FacetBuddyFactory(s.facetBuddyFactory).predictBuddyAddress(forUser)\n }\n function(:bridgeOut, { amount: :uint256 }, :public) {\n whenNotPaused!\n withdrawalId = tx.current_transaction_hash\n require(s.userWithdrawalId[msg.sender] == bytes32(0), \"Withdrawal pending\")\n require(s.withdrawalIdAmount[withdrawalId] == 0, \"Already bridged out\")\n require(amount \u003e 0, \"Invalid amount\")\n s.userWithdrawalId[msg.sender] = withdrawalId\n s.withdrawalIdAmount[withdrawalId] = amount\n _burn(from: msg.sender, amount: amount)\n emit(:InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId)\n }\n function(:markWithdrawalComplete, { to: :address, withdrawalId: :bytes32 }, :public) {\n require(msg.sender == s.trustedSmartContract, \"Only the trusted smart contract can mark withdrawals as complete\")\n require(s.userWithdrawalId[to] == withdrawalId, \"Withdrawal id not found\")\n amount = s.withdrawalIdAmount[withdrawalId]\n s.withdrawalIdAmount[withdrawalId] = 0\n s.userWithdrawalId[to] = bytes32(0)\n emit(:WithdrawalComplete, to: to, amount: amount, withdrawalId: withdrawalId)\n }\n function(:pause, :public) {\n onlyOwner!\n _pause\n }\n function(:unpause, :public) {\n onlyOwner!\n _unpause\n }\n}\n"}}}
data:application/vnd.facet.system+json;rule=esip6,{"op":"updateSupportedContracts","data":["0x048cc2bb0751a06b409ab438941182f7c4e753eb2b3c5a40b338d7c44d7b43d1","0x4bddad53945dd1d0b155207b1e6a9d641a7658788ac6b35e02bbfae63ccdd6f0","0xa2a9d5bf9901d7a15ae08ceb568dac12d14dab2d5994ec8037feae7aeeb4e2c7","0xcae364f38cd61ae19f32d460fc14eb8e62ebd0a5cc26b1a95dfac3d5d834c1aa","0x9022ced2f52aee8b28119f0490767a6e0b80b492642364382e609b6e84d85ce0","0x52c3226b3e5045a92e0a3975978997b7e5af223021470a1deb14211511dd04c9","0xa46f3d0539f8556dc2f86b63e68249db6c1db193da387d780aaded983f4c7ae4","0xa26bdad3c05ec5c4a0e234b5f755ca9cf7311dd857250a183b74a779e3c96ef8","0xb71fdafae3610cb8e74900b8e6d43163aaab54cc6e6c54ff5b7c7570a2dabe5c","0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","0xb5b742d755877bac6b80e2f0af4d97792fce2b2a58ff0ee2274b86eac91e977f","0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","0xb1b0ed1e4a8c9c9b0210f267137e368f782453e41f622fa8cf68296d04c84c88","0xe46dfedf0c0e9a0985d5151f5844bea96e5ac147cd9ddc7daa22a0899659d2f5","0x958b66f80d8d14e5c2129434bb8c78aabb60b5cfb7113224102e1a9a07c77ac5","0x2dce6b589dd5a5bedc5d9a91806a6cc5f16ae52c0f8dae730a886d7212db2dfd","0xd6c73897c5441fa221f1f0ebaee84241099b58f9cf51f6f4bcaf6bac4c29756d","0x45b224f1320c602a827823099dc4e7f596baf4227f919102a7f80523834edb02"]}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x77a9bb1ad908cdab503f8da9d0891575524064d6","function":"upgrade","args":{"newHash":"0x048cc2bb0751a06b409ab438941182f7c4e753eb2b3c5a40b338d7c44d7b43d1","newSource":""}}}
G_data:application/vnd.facet.tx+json;rule=esip6,{"op":"create","data":{"source_code":"pragma(:rubidity, \"1.0.0\")\ncontract(:ERC20, abstract: true) {\n event(:Transfer, { from: :address, to: :address, amount: :uint256 })\n event(:Approval, { owner: :address, spender: :address, amount: :uint256 })\n string(:public, :name)\n string(:public, :symbol)\n uint8(:public, :decimals)\n uint256(:public, :totalSupply)\n mapping(({ address: :uint256 }), :public, :balanceOf)\n mapping(({ address: mapping(address: :uint256) }), :public, :allowance)\n constructor(name: :string, symbol: :string, decimals: :uint8) {\n s.name=name\n s.symbol=symbol\n s.decimals=decimals\n }\n function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n s.allowance[msg.sender][spender] = amount\n emit(:Approval, owner: msg.sender, spender: spender, amount: amount)\n return true\n }\n function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n require(s.balanceOf[msg.sender] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[msg.sender] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: msg.sender, to: to, amount: amount)\n return true\n }\n function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n allowed = s.allowance[from][msg.sender]\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n require(allowed \u003e= amount, \"Insufficient allowance\")\n s.allowance[from][msg.sender] = allowed - amount\n s.balanceOf[from] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: from, to: to, amount: amount)\n return true\n }\n function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {\n s.totalSupply += amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: address(0), to: to, amount: amount)\n }\n function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[from] -= amount\n s.totalSupply -= amount\n emit(:Transfer, from: from, to: address(0), amount: amount)\n }\n}\ncontract(:ERC721, abstract: true) {\n event(:Transfer, { from: :address, to: :address, id: :uint256 })\n event(:Approval, { owner: :address, spender: :address, id: :uint256 })\n event(:ApprovalForAll, { owner: :address, operator: :address, approved: :bool })\n string(:public, :name)\n string(:public, :symbol)\n mapping(({ uint256: :address }), :internal, :_ownerOf)\n mapping(({ address: :uint256 }), :internal, :_balanceOf)\n mapping(({ uint256: :address }), :public, :getApproved)\n mapping(({ address: mapping(address: :bool) }), :public, :isApprovedForAll)\n constructor(name: :string, symbol: :string) {\n s.name=name\n s.symbol=symbol\n }\n function(:ownerOf, { id: :uint256 }, :public, :view, :virtual, returns: :address) {\n owner = s._ownerOf[id]\n require(owner != address(0), \"ERC721: owner query for nonexistent token\")\n return owner\n }\n function(:balanceOf, { owner: :address }, :public, :view, :virtual, returns: :uint256) {\n require(owner != address(0), \"ERC721: balance query for nonexistent owner\")\n return s._balanceOf[owner]\n }\n function(:approve, { spender: :address, id: :uint256 }, :public, :virtual) {\n owner = ownerOf(id)\n require(msg.sender == owner || s.isApprovedForAll[owner][msg.sender], \"ERC721: msg.sender not authorized to approve\")\n s.getApproved[id] = spender\n emit(:Approval, owner: owner, spender: spender, id: id)\n }\n function(:setApprovalForAll, { operator: :address, approved: :bool }, :public, :virtual) {\n s.isApprovedForAll[msg.sender][operator] = approved\n emit(:ApprovalForAll, owner: msg.sender, operator: operator, approved: approved)\n }\n function(:transferFrom, { from: :address, to: :address, id: :uint256 }, :public, :virtual) {\n require(from == ownerOf(id), \"ERC721: transfer of token that is not own\")\n require(to != address(0), \"ERC721: transfer to the zero address\")\n require(isApprovedOrOwner(spender: msg.sender, id: id), \"ERC721: msg.sender not authorized to call transferFrom\")\n s._balanceOf[from] -= 1\n s._balanceOf[to] += 1\n s._ownerOf[id] = to\n s.getApproved[id] = address(0)\n emit(:Transfer, from: from, to: to, id: id)\n }\n function(:isApprovedOrOwner, { spender: :address, id: :uint256 }, :public, :view, :virtual, returns: :bool) {\n owner = ownerOf(id)\n spender == owner || s.getApproved[id] == spender || s.isApprovedForAll[owner][spender]\n }\n function(:_exists, { id: :uint256 }, :internal, :view, :virtual, returns: :bool) {\n return s._ownerOf[id] != address(0)\n }\n function(:_mint, { to: :address, id: :uint256 }, :internal, :virtual) {\n require(to != address(0), \"ERC721: mint to the zero address\")\n require(s._ownerOf[id] == address(0), \"ERC721: token already minted\")\n s._balanceOf[to] += 1\n s._ownerOf[id] = to\n emit(:Transfer, from: address(0), to: to, id: id)\n }\n function(:_burn, { id: :uint256 }, :internal, :virtual) {\n owner = s._ownerOf[id]\n require(owner != address(0), \"ERC721: burn of nonexistent token\")\n s._balanceOf[owner] -= 1\n s._ownerOf[id] = address(0)\n s.getApproved[id] = address(0)\n emit(:Transfer, from: owner, to: address(0), id: id)\n }\n function(:tokenURI, { id: :uint256 }, :public, :view, :virtual, returns: :string) {\n }\n}\ncontract(:INFTCollection01, abstract: true) {\n function(:owner, :external, :view, returns: :address)\n}\ncontract(:Upgradeable, abstract: true) {\n address(:public, :upgradeAdmin)\n event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })\n event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })\n constructor(upgradeAdmin: :address) {\n s.upgradeAdmin=upgradeAdmin\n }\n function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n s.upgradeAdmin=newUpgradeAdmin\n emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)\n }\n function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {\n upgrade(newHash: newHash, newSource: newSource)\n (success, data) = address(this).call(migrationCalldata)\n require(success, \"Migration failed\")\n }\n function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {\n currentHash = this.currentInitCodeHash\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n this.upgradeImplementation(newHash, newSource)\n emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)\n }\n}\ncontract(:TokenUpgradeRenderer02, is: :Upgradeable, upgradeable: true) {\n event(:CollectionInitialized, { collection: :address, contractInfo: :ContractInfo, initialLevel: :TokenUpgradeLevel })\n event(:UpgradeLevelUpdated, { collection: :address, index: :uint256, name: :string, imageURI: :string, animationURI: :string, startTime: :uint256, endTime: :uint256, newRecord: :bool })\n event(:TokenUpgraded, { collection: :address, tokenId: :uint256, upgradeLevel: :uint256 })\n event(:ContractInfoUpdated, { collection: :address, newInfo: :ContractInfo })\n struct(:TokenUpgradeLevel) {\n string(:name)\n string(:imageURI)\n string(:animationURI)\n string(:extraAttributesJson)\n uint256(:startTime)\n uint256(:endTime)\n }\n struct(:TokenStatus) {\n uint256(:upgradeLevel)\n uint256(:lastUpgradeTime)\n }\n struct(:ContractInfo) {\n string(:name)\n string(:description)\n string(:imageURI)\n }\n mapping(({ address: array(:TokenUpgradeLevel, 1) }), :public, :tokenUpgradeLevelsByCollection)\n mapping(({ address: mapping(uint256: :TokenStatus) }), :public, :tokenStatusByCollection)\n mapping(({ address: :ContractInfo }), :public, :contractInfoByCollection)\n mapping(({ address: mapping(uint256: array(:string)) }), :public, :tokenUpgradeLevelImageURIsByCollection)\n mapping(({ address: mapping(uint256: :bytes32) }), :public, :blockHashByTokenLevelByCollection)\n uint256(:public, :perUpgradeFee)\n address(:public, :feeTo)\n address(:public, :WETH)\n uint256(:public, :maxUpgradeLevelCount)\n constructor(perUpgradeFee: :uint256, feeTo: :address, weth: :address) {\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n s.maxUpgradeLevelCount=30\n s.perUpgradeFee=perUpgradeFee\n s.feeTo=feeTo\n s.WETH=weth\n }\n function(:addUpgradeLevel, { collection: :address, newLevel: :TokenUpgradeLevel, imageURIs: [:string] }, :public) {\n requireSenderAdmin(collection)\n lastLevel = s.tokenUpgradeLevelsByCollection[collection].last\n require(newLevel.endTime \u003e newLevel.startTime, \"End time must be after start time\")\n require(newLevel.startTime \u003e lastLevel.endTime, \"Start time must be after last level end time\")\n require(s.tokenUpgradeLevelsByCollection[collection].length + 1 \u003c= s.maxUpgradeLevelCount, \"Max upgrade level count reached\")\n require(imageURIs.length \u003c= 25, \"Max 25 image URIs allowed\")\n s.tokenUpgradeLevelsByCollection[collection].push(newLevel)\n index = s.tokenUpgradeLevelsByCollection[collection].length - 1\n s.tokenUpgradeLevelImageURIsByCollection[collection][index] = imageURIs\n s.blockHashByTokenLevelByCollection[collection][index] = blockhash(block.number)\n emit(:UpgradeLevelUpdated, collection: collection, index: s.tokenUpgradeLevelsByCollection[collection].length - 1, name: newLevel.name, imageURI: newLevel.imageURI, animationURI: newLevel.animationURI, startTime: newLevel.startTime, endTime: newLevel.endTime, newRecord: true)\n }\n function(:editUpgradeLevel, { collection: :address, index: :uint256, newLevel: :TokenUpgradeLevel, imageURIs: [:string] }, :public) {\n requireSenderAdmin(collection)\n require(imageURIs.length \u003c= 25, \"Max 25 image URIs allowed\")\n editingFirstLevel = index == 0\n editingLastLevel = index == s.tokenUpgradeLevelsByCollection[collection].length.-(1)\n unless editingLastLevel\n nextLevel = s.tokenUpgradeLevelsByCollection[collection][index + 1]\n require(newLevel.endTime \u003c nextLevel.startTime, \"End time must be before next level start time\")\n end\n if editingFirstLevel\n newLevel.startTime=0\n newLevel.endTime=0\n else\n precedingLevel = s.tokenUpgradeLevelsByCollection[collection][index - 1]\n require(newLevel.startTime \u003e precedingLevel.endTime, \"Start time must be after preceding level end time\")\n require(newLevel.endTime \u003e newLevel.startTime, \"End time must be after start time\")\n end\n s.tokenUpgradeLevelsByCollection[collection][index] = newLevel\n s.tokenUpgradeLevelImageURIsByCollection[collection][index] = imageURIs\n emit(:UpgradeLevelUpdated, collection: collection, index: index, name: newLevel.name, imageURI: newLevel.imageURI, animationURI: newLevel.animationURI, startTime: newLevel.startTime, endTime: newLevel.endTime, newRecord: false)\n }\n function(:activeUpgradeLevelIndex, { collection: :address }, :public, :view, returns: :uint256) {\n forLoop(condition: -\u003e(i) {\n i \u003c s.tokenUpgradeLevelsByCollection[collection].length\n }) { |i|\n level = s.tokenUpgradeLevelsByCollection[collection][i]\n if level.startTime \u003c= block.timestamp \u0026\u0026 level.endTime \u003e block.timestamp\n return i\n else\n if level.startTime \u003e block.timestamp\n return 0\n end\n end\n }\n return 0\n }\n function(:activeUpgradeLevel, { collection: :address }, :public, :view, returns: :TokenUpgradeLevel) {\n index = activeUpgradeLevelIndex(collection)\n return index == 0 ? TokenUpgradeLevel() : s.tokenUpgradeLevelsByCollection[collection][index]\n }\n function(:_upgradeToken, { collection: :address, tokenId: :uint256, activeUpgrade: :TokenUpgradeLevel }, :internal) {\n require(ERC721(collection).isApprovedOrOwner(spender: msg.sender, id: tokenId), \"TokenUpgradeRenderer: msg.sender not authorized to upgrade id #{tokenId.toString}\")\n tokenStatus = s.tokenStatusByCollection[collection][tokenId]\n require(tokenStatus.lastUpgradeTime \u003c activeUpgrade.startTime, \"TokenUpgradeRenderer: Token already upgraded during this period\")\n targetLevelIndex = tokenStatus.upgradeLevel + 1\n require(targetLevelIndex \u003c s.tokenUpgradeLevelsByCollection[collection].length, \"TokenUpgradeRenderer: No more upgrade levels\")\n tokenStatus.upgradeLevel=targetLevelIndex\n tokenStatus.lastUpgradeTime=block.timestamp\n emit(:TokenUpgraded, collection: collection, tokenId: tokenId, upgradeLevel: tokenStatus.upgradeLevel)\n }\n function(:upgradeMultipleTokens, { collection: :address, tokenIds: [:uint256] }, :public) {\n require(tokenIds.length \u003c= 100, \"TokenUpgradeRenderer: Cannot upgrade more than 50 tokens at once\")\n totalFee = s.perUpgradeFee * tokenIds.length\n if totalFee \u003e 0 \u0026\u0026 s.feeTo != address(0)\n ERC20(s.WETH).transferFrom(msg.sender, s.feeTo, totalFee)\n end\n activeUpgradeIndex = activeUpgradeLevelIndex(collection)\n require(activeUpgradeIndex \u003e 0, \"TokenUpgradeRenderer: No active upgrade level\")\n activeUpgrade = s.tokenUpgradeLevelsByCollection[collection][activeUpgradeIndex]\n forLoop(condition: -\u003e(i) {\n i \u003c tokenIds.length\n }) { |i|\n _upgradeToken(collection: collection, tokenId: tokenIds[i], activeUpgrade: activeUpgrade)\n }\n }\n function(:setContractInfo, { collection: :address, info: :ContractInfo }, :public) {\n requireSenderAdmin(collection)\n s.contractInfoByCollection[collection] = info\n emit(:ContractInfoUpdated, collection: collection, newInfo: info)\n }\n function(:lastUpgradeLevel, { collection: :address, tokenId: :uint256 }, :public, :view, returns: :TokenUpgradeLevel) {\n status = s.tokenStatusByCollection[collection][tokenId]\n upgradeTime = status.lastUpgradeTime\n if upgradeTime == 0\n return TokenUpgradeLevel()\n end\n forLoop(condition: -\u003e(i) {\n i \u003c s.tokenUpgradeLevelsByCollection[collection].length\n }) { |i|\n level = s.tokenUpgradeLevelsByCollection[collection][i]\n if level.startTime \u003c= upgradeTime \u0026\u0026 level.endTime \u003e upgradeTime\n return level\n end\n }\n return TokenUpgradeLevel()\n }\n function(:tokenURI, { tokenId: :uint256 }, :external, :view, returns: :string) {\n collection = msg.sender\n status = s.tokenStatusByCollection[collection][tokenId]\n upgradeLevel = s.tokenUpgradeLevelsByCollection[collection][status.upgradeLevel]\n name_json = json.stringify(\"#{upgradeLevel.name} ##{tokenId.toString}\")\n description_json = json.stringify(s.contractInfoByCollection[collection].description)\n uriAryLength = s.tokenUpgradeLevelImageURIsByCollection[collection][status.upgradeLevel].length\n imageURI = if uriAryLength \u003e 0\n blockhash = s.blockHashByTokenLevelByCollection[collection][status.upgradeLevel]\n entropy = uint256(keccak256(abi.encodePacked(collection, blockhash, tokenId)))\n s.tokenUpgradeLevelImageURIsByCollection[collection][status.upgradeLevel][entropy % uriAryLength]\n else\n upgradeLevel.imageURI\n end\n image_field = if imageURI.length == 0\n \"\"\n else\n \"\\\"image\\\": #{json.stringify(imageURI)},\\n\"\n end\n animation_url_field = if upgradeLevel.animationURI.length == 0\n \"\"\n else\n \"\\\"animation_url\\\": #{json.stringify(upgradeLevel.animationURI)},\\n\"\n end\n last_level = lastUpgradeLevel(collection: collection, tokenId: tokenId)\n last_upgrade_level_json = if last_level != TokenUpgradeLevel()\n \", {\\\"trait_type\\\": \\\"Last Upgrade Level\\\", \\\"value\\\": #{json.stringify(last_level.name)}}\\n\"\n else\n \"\"\n end\n extra_attributes_json = if upgradeLevel.extraAttributesJson != \"\"\n \", \" + upgradeLevel.extraAttributesJson\n else\n \"\"\n end\n json_data = \u003c\u003c-HEREDOC\n {\n \"name\": #{name_json},\n \"description\": #{description_json},\n #{image_field}\n #{animation_url_field}\n \"attributes\": [\n {\"trait_type\": \"Number\", \"display_type\": \"number\", \"value\": #{tokenId.toString}},\n {\"trait_type\": \"Level\", \"value\": #{json.stringify(upgradeLevel.name)}}\n #{last_upgrade_level_json}\n #{extra_attributes_json}\n ]\n }\n HEREDOC\n \"data:application/json;base64,\" + json_data.base64Encode\n }\n function(:initializeWithData, { contractInfo: :ContractInfo, initialLevel: :TokenUpgradeLevel }, :external) {\n setContractInfo(collection: msg.sender, info: contractInfo)\n editUpgradeLevel(collection: msg.sender, index: 0, newLevel: initialLevel)\n emit(:CollectionInitialized, collection: msg.sender, contractInfo: contractInfo, initialLevel: initialLevel)\n }\n function(:contractURI, :external, :view, returns: :string) {\n collection = msg.sender\n contractInfo = s.contractInfoByCollection[collection]\n json_data = json.stringify(name: contractInfo.name, description: contractInfo.description, image: contractInfo.imageURI)\n \"data:application/json;base64,\" + json_data.base64Encode\n }\n function(:upgradeLevelCount, { collection: :address }, :public, :view, returns: :uint256) {\n return s.tokenUpgradeLevelsByCollection[collection].length\n }\n function(:requireSenderAdmin, { target: :address }, :internal, :view) {\n require(target == msg.sender || INFTCollection01(target).owner == msg.sender, \"Admin access only\")\n }\n function(:setFeeTo, { feeTo: :address }, :public) {\n require(msg.sender == s.feeTo, \"Only feeTo can change feeTo\")\n s.feeTo=feeTo\n nil\n }\n}\n","init_code_hash":"0x048cc2bb0751a06b409ab438941182f7c4e753eb2b3c5a40b338d7c44d7b43d1","args":{"perUpgradeFee":0,"feeTo":"0x0000000000000000000000000000000000000000","weth":"0x0000000000000000000000000000000000000000"}}}
data:application/vnd.facet.system+json;rule=esip6,{"op":"updateSupportedContracts","data":["0x048cc2bb0751a06b409ab438941182f7c4e753eb2b3c5a40b338d7c44d7b43d1","0x4bddad53945dd1d0b155207b1e6a9d641a7658788ac6b35e02bbfae63ccdd6f0","0xa2a9d5bf9901d7a15ae08ceb568dac12d14dab2d5994ec8037feae7aeeb4e2c7","0xcae364f38cd61ae19f32d460fc14eb8e62ebd0a5cc26b1a95dfac3d5d834c1aa","0x9022ced2f52aee8b28119f0490767a6e0b80b492642364382e609b6e84d85ce0","0x52c3226b3e5045a92e0a3975978997b7e5af223021470a1deb14211511dd04c9","0xdf13c05ccd7d54d7b9a8f3e2be83630c4d38d8bed6ce7e8f6a1a15466f3e9d58","0xa26bdad3c05ec5c4a0e234b5f755ca9cf7311dd857250a183b74a779e3c96ef8","0xb71fdafae3610cb8e74900b8e6d43163aaab54cc6e6c54ff5b7c7570a2dabe5c","0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","0xb5b742d755877bac6b80e2f0af4d97792fce2b2a58ff0ee2274b86eac91e977f","0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","0xb1b0ed1e4a8c9c9b0210f267137e368f782453e41f622fa8cf68296d04c84c88","0xe46dfedf0c0e9a0985d5151f5844bea96e5ac147cd9ddc7daa22a0899659d2f5","0x958b66f80d8d14e5c2129434bb8c78aabb60b5cfb7113224102e1a9a07c77ac5","0x2dce6b589dd5a5bedc5d9a91806a6cc5f16ae52c0f8dae730a886d7212db2dfd","0xd6c73897c5441fa221f1f0ebaee84241099b58f9cf51f6f4bcaf6bac4c29756d","0x45b224f1320c602a827823099dc4e7f596baf4227f919102a7f80523834edb02"]}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x1673540243e793b0e77c038d4a88448eff524dce","function":"transfer","args":{"to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","amount":"7270063449750000000"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"54251068813973677252","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"1000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0x26231ad975456d53682e1b6364e9e005886281e7"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"2053916649100949739346","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"1000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0x5d0dc4380fc8d501795aec7e7a908cb25c4131c6"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"514552672332730470036","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"1000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0xa38ad4c62a70e14619fa56548bb5e11381d58ff6"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"69558593272812610956","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"100000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0x55ab0390a89fed8992e3affbf61d102490735e24"}}}
data:application/vnd.facet.system+json;rule=esip6,{"op":"updateSupportedContracts","data":["0xa2a9d5bf9901d7a15ae08ceb568dac12d14dab2d5994ec8037feae7aeeb4e2c7","0xcae364f38cd61ae19f32d460fc14eb8e62ebd0a5cc26b1a95dfac3d5d834c1aa","0x9022ced2f52aee8b28119f0490767a6e0b80b492642364382e609b6e84d85ce0","0x52c3226b3e5045a92e0a3975978997b7e5af223021470a1deb14211511dd04c9","0xdf13c05ccd7d54d7b9a8f3e2be83630c4d38d8bed6ce7e8f6a1a15466f3e9d58","0xa26bdad3c05ec5c4a0e234b5f755ca9cf7311dd857250a183b74a779e3c96ef8","0xb71fdafae3610cb8e74900b8e6d43163aaab54cc6e6c54ff5b7c7570a2dabe5c","0x2dbec15cf7c23393357f0336e0058ca1c48e8f694324a6d95334f539598d9bf5","0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","0xb5b742d755877bac6b80e2f0af4d97792fce2b2a58ff0ee2274b86eac91e977f","0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","0xb1b0ed1e4a8c9c9b0210f267137e368f782453e41f622fa8cf68296d04c84c88","0xe46dfedf0c0e9a0985d5151f5844bea96e5ac147cd9ddc7daa22a0899659d2f5","0x958b66f80d8d14e5c2129434bb8c78aabb60b5cfb7113224102e1a9a07c77ac5","0x2dce6b589dd5a5bedc5d9a91806a6cc5f16ae52c0f8dae730a886d7212db2dfd","0xd6c73897c5441fa221f1f0ebaee84241099b58f9cf51f6f4bcaf6bac4c29756d","0x45b224f1320c602a827823099dc4e7f596baf4227f919102a7f80523834edb02"]}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"79203993704135359231","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"1000000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0x55ab0390a89fed8992e3affbf61d102490735e24"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x1673540243e793b0e77c038d4a88448eff524dce","function":"transfer","args":{"amount":"14582996382499500000","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"create","data":{"init_code_hash":"0xb5b742d755877bac6b80e2f0af4d97792fce2b2a58ff0ee2274b86eac91e977f","args":{"name":"test","symbol":"test","maxSupply":"1","baseURI":"","weth":"0x1673540243e793b0e77c038d4a88448eff524dce","perMintFee":"0","feeTo":"0x2052051a0474fb0b98283b3f38c13b0b0b6a3677"},"source_code":"pragma(:rubidity, \"1.0.0\")\ncontract(:ERC20, abstract: true) {\n event(:Transfer, { from: :address, to: :address, amount: :uint256 })\n event(:Approval, { owner: :address, spender: :address, amount: :uint256 })\n string(:public, :name)\n string(:public, :symbol)\n uint8(:public, :decimals)\n uint256(:public, :totalSupply)\n mapping(({ address: :uint256 }), :public, :balanceOf)\n mapping(({ address: mapping(address: :uint256) }), :public, :allowance)\n constructor(name: :string, symbol: :string, decimals: :uint8) {\n s.name=name\n s.symbol=symbol\n s.decimals=decimals\n }\n function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n s.allowance[msg.sender][spender] = amount\n emit(:Approval, owner: msg.sender, spender: spender, amount: amount)\n return true\n }\n function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n require(s.balanceOf[msg.sender] >= amount, \"Insufficient balance\")\n s.balanceOf[msg.sender] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: msg.sender, to: to, amount: amount)\n return true\n }\n function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n allowed = s.allowance[from][msg.sender]\n require(s.balanceOf[from] >= amount, \"Insufficient balance\")\n require(allowed >= amount, \"Insufficient allowance\")\n s.allowance[from][msg.sender] = allowed - amount\n s.balanceOf[from] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: from, to: to, amount: amount)\n return true\n }\n function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {\n s.totalSupply += amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: address(0), to: to, amount: amount)\n }\n function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {\n require(s.balanceOf[from] >= amount, \"Insufficient balance\")\n s.balanceOf[from] -= amount\n s.totalSupply -= amount\n emit(:Transfer, from: from, to: address(0), amount: amount)\n }\n}\ncontract(:ERC2981, abstract: true) {\n event(:DefaultRoyaltyUpdated, { receiver: :address, feeNumerator: :uint96 })\n event(:TokenRoyaltyUpdated, { tokenId: :uint256, receiver: :address, feeNumerator: :uint96 })\n mapping(({ uint256: :address }), :internal, :_tokenIdToReceiver)\n mapping(({ uint256: :uint96 }), :internal, :_tokenIdToFeeNumerator)\n address(:internal, :_defaultRoyaltyReceiver)\n uint96(:internal, :_defaultFeeNumerator)\n function(:royaltyInfo, { tokenId: :uint256, salePrice: :uint256 }, :public, :view, :virtual, returns: { receiver: :address, royaltyAmount: :uint256 }) {\n receiver = s._tokenIdToReceiver[tokenId]\n feeNumerator = s._tokenIdToFeeNumerator[tokenId]\n if receiver == address(0)\n receiver = s._defaultRoyaltyReceiver\n feeNumerator = s._defaultFeeNumerator\n end\n royaltyAmount = (salePrice * feeNumerator).div(_feeDenominator)\n return { receiver: receiver, royaltyAmount: royaltyAmount }\n }\n function(:_setDefaultRoyalty, { receiver: :address, feeNumerator: :uint96 }, :internal, :virtual) {\n require(feeNumerator <= _feeDenominator, \"ERC2981InvalidDefaultRoyalty\")\n require(receiver != address(0), \"ERC2981InvalidDefaultRoyaltyReceiver: address(0)\")\n s._defaultRoyaltyReceiver=receiver\n s._defaultFeeNumerator=feeNumerator\n emit(:DefaultRoyaltyUpdated, receiver: receiver, feeNumerator: feeNumerator)\n }\n function(:_deleteDefaultRoyalty, :internal, :virtual) {\n s._defaultRoyaltyReceiver=address(0)\n s._defaultFeeNumerator=0\n emit(:DefaultRoyaltyUpdated, receiver: address(0), feeNumerator: 0)\n }\n function(:_setTokenRoyalty, { tokenId: :uint256, receiver: :address, feeNumerator: :uint96 }, :internal, :virtual) {\n require(feeNumerator <= _feeDenominator, \"ERC2981InvalidTokenRoyalty\")\n require(receiver != address(0), \"ERC2981InvalidTokenRoyaltyReceiver\")\n s._tokenIdToReceiver[tokenId] = receiver\n s._tokenIdToFeeNumerator[tokenId] = feeNumerator\n emit(:TokenRoyaltyUpdated, tokenId: tokenId, receiver: receiver, feeNumerator: feeNumerator)\n }\n function(:_deleteTokenRoyalty, { tokenId: :uint256 }, :internal, :virtual) {\n s._tokenIdToReceiver[tokenId] = address(0)\n s._tokenIdToFeeNumerator[tokenId] = 0\n emit(:TokenRoyaltyUpdated, tokenId: tokenId, receiver: address(0), feeNumerator: 0)\n }\n function(:_feeDenominator, :internal, :view, :virtual, returns: :uint96) {\n return 10000\n }\n function(:supportsERC2981, :public, :pure, :virtual, returns: :bool) {\n return true\n }\n}\ncontract(:ERC721, abstract: true) {\n event(:Transfer, { from: :address, to: :address, id: :uint256 })\n event(:Approval, { owner: :address, spender: :address, id: :uint256 })\n event(:ApprovalForAll, { owner: :address, operator: :address, approved: :bool })\n string(:public, :name)\n string(:public, :symbol)\n mapping(({ uint256: :address }), :internal, :_ownerOf)\n mapping(({ address: :uint256 }), :internal, :_balanceOf)\n mapping(({ uint256: :address }), :public, :getApproved)\n mapping(({ address: mapping(address: :bool) }), :public, :isApprovedForAll)\n constructor(name: :string, symbol: :string) {\n s.name=name\n s.symbol=symbol\n }\n function(:ownerOf, { id: :uint256 }, :public, :view, :virtual, returns: :address) {\n owner = s._ownerOf[id]\n require(owner != address(0), \"ERC721: owner query for nonexistent token\")\n return owner\n }\n function(:balanceOf, { owner: :address }, :public, :view, :virtual, returns: :uint256) {\n require(owner != address(0), \"ERC721: balance query for nonexistent owner\")\n return s._balanceOf[owner]\n }\n function(:approve, { spender: :address, id: :uint256 }, :public, :virtual) {\n owner = ownerOf(id)\n require(msg.sender == owner || s.isApprovedForAll[owner][msg.sender], \"ERC721: msg.sender not authorized to approve\")\n s.getApproved[id] = spender\n emit(:Approval, owner: owner, spender: spender, id: id)\n }\n function(:setApprovalForAll, { operator: :address, approved: :bool }, :public, :virtual) {\n s.isApprovedForAll[msg.sender][operator] = approved\n emit(:ApprovalForAll, owner: msg.sender, operator: operator, approved: approved)\n }\n function(:transferFrom, { from: :address, to: :address, id: :uint256 }, :public, :virtual) {\n require(from == ownerOf(id), \"ERC721: transfer of token that is not own\")\n require(to != address(0), \"ERC721: transfer to the zero address\")\n require(isApprovedOrOwner(spender: msg.sender, id: id), \"ERC721: msg.sender not authorized to call transferFrom\")\n s._balanceOf[from] -= 1\n s._balanceOf[to] += 1\n s._ownerOf[id] = to\n s.getApproved[id] = address(0)\n emit(:Transfer, from: from, to: to, id: id)\n }\n function(:isApprovedOrOwner, { spender: :address, id: :uint256 }, :public, :view, :virtual, returns: :bool) {\n owner = ownerOf(id)\n spender == owner || s.getApproved[id] == spender || s.isApprovedForAll[owner][spender]\n }\n function(:_exists, { id: :uint256 }, :internal, :view, :virtual, returns: :bool) {\n return s._ownerOf[id] != address(0)\n }\n function(:_mint, { to: :address, id: :uint256 }, :internal, :virtual) {\n require(to != address(0), \"ERC721: mint to the zero address\")\n require(s._ownerOf[id] == address(0), \"ERC721: token already minted\")\n s._balanceOf[to] += 1\n s._ownerOf[id] = to\n emit(:Transfer, from: address(0), to: to, id: id)\n }\n function(:_burn, { id: :uint256 }, :internal, :virtual) {\n owner = s._ownerOf[id]\n require(owner != address(0), \"ERC721: burn of nonexistent token\")\n s._balanceOf[owner] -= 1\n s._ownerOf[id] = address(0)\n s.getApproved[id] = address(0)\n emit(:Transfer, from: owner, to: address(0), id: id)\n }\n function(:tokenURI, { id: :uint256 }, :public, :view, :virtual, returns: :string) {\n }\n}\ncontract(:IEditionMetadataRenderer01, abstract: true) {\n function(:tokenURI, { tokenId: :uint256 }, :external, :view, returns: :string)\n function(:contractURI, :external, :view, returns: :string)\n function(:initializeWithData, { data: [:string] }, :external)\n}\ncontract(:MerkleProof, abstract: true) {\n function(:verify, { proof: [:bytes32], root: :bytes32, leaf: :bytes32 }, :internal, :pure, returns: :bool) {\n processProof(proof, leaf) == root\n }\n function(:processProof, { proof: [:bytes32], leaf: :bytes32 }, :internal, :pure, returns: :bytes32) {\n computedHash = leaf\n forLoop(condition: ->(i) {\n i < proof.length\n }, max_iterations: 25) { |i|\n computedHash = _hashPair(computedHash, proof[i])\n }\n computedHash\n }\n function(:_hashPair, { a: :bytes32, b: :bytes32 }, :private, :pure, returns: :bytes32) {\n if a.cast(:uint256) < b.cast(:uint256)\n _efficientHash(a, b)\n else\n _efficientHash(b, a)\n end\n }\n function(:_efficientHash, { a: :bytes32, b: :bytes32 }, :private, :pure, returns: :bytes32) {\n keccak256(abi.encodePacked(a, b))\n }\n}\ncontract(:Ownable, abstract: true) {\n address(:public, :owner)\n event(:OwnershipTransferred, { previousOwner: :address, newOwner: :address })\n constructor(owner: :address) {\n s.owner=owner\n }\n function(:transferOwnership, { newOwner: :address }, :public) {\n onlyOwner!\n previousOwner = s.owner\n s.owner=newOwner\n emit(:OwnershipTransferred, previousOwner: previousOwner, newOwner: newOwner)\n }\n function(:onlyOwner!, :internal) {\n require(msg.sender == s.owner, \"msg.sender is not the owner\")\n }\n}\ncontract(:Pausable, abstract: true) {\n bool(:public, :paused)\n event(:Paused, { account: :address })\n event(:Unpaused, { account: :address })\n constructor(initialPauseState: :bool) {\n s.paused=initialPauseState\n }\n function(:_pause, :internal) {\n s.paused=true\n emit(:Paused, account: msg.sender)\n }\n function(:_unpause, :internal) {\n s.paused=false\n emit(:Unpaused, account: msg.sender)\n }\n function(:whenPaused!, :internal) {\n require(s.paused, \"Contract is not paused\")\n }\n function(:whenNotPaused!, :internal) {\n require(!s.paused, \"Contract is paused\")\n }\n}\ncontract(:Upgradeable, abstract: true) {\n address(:public, :upgradeAdmin)\n event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })\n event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })\n constructor(upgradeAdmin: :address) {\n s.upgradeAdmin=upgradeAdmin\n }\n function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n s.upgradeAdmin=newUpgradeAdmin\n emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)\n }\n function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {\n upgrade(newHash: newHash, newSource: newSource)\n (success, data) = address(this).call(migrationCalldata)\n require(success, \"Migration failed\")\n }\n function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {\n currentHash = this.currentInitCodeHash\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n this.upgradeImplementation(newHash, newSource)\n emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)\n }\n}\ncontract(:NFTCollection01, is: [:ERC721, :ERC2981, :Upgradeable, :Ownable, :Pausable, :MerkleProof], upgradeable: true) {\n event(:Minted, { to: :address, amount: :uint256, mintPrice: :uint256, totalCost: :uint256, newTotalSupply: :uint256, isPublic: :bool })\n event(:PublicMaxPerAddressUpdated, { publicMaxPerAddress: :uint256 })\n event(:PublicMintStartUpdated, { publicMintStart: :uint256 })\n event(:PublicMintEndUpdated, { publicMintEnd: :uint256 })\n event(:PublicMintPriceUpdated, { publicMintPrice: :uint256 })\n event(:AllowListMerkleRootUpdated, { allowListMerkleRoot: :bytes32 })\n event(:AllowListMaxPerAddressUpdated, { allowListMaxPerAddress: :uint256 })\n event(:AllowListMintStartUpdated, { allowListMintStart: :uint256 })\n event(:AllowListMintEndUpdated, { allowListMintEnd: :uint256 })\n event(:AllowListMintPriceUpdated, { allowListMintPrice: :uint256 })\n event(:MaxSupplyUpdated, { maxSupply: :uint256 })\n event(:BaseURIUpdated, { baseURI: :string })\n event(:MetadataRendererUpdated, { metadataRenderer: :string })\n uint256(:public, :maxSupply)\n uint256(:public, :totalSupply)\n uint256(:public, :nextTokenId)\n uint256(:public, :maxPerMint)\n string(:public, :baseURI)\n address(:public, :WETH)\n address(:public, :metadataRenderer)\n uint256(:public, :publicMaxPerAddress)\n uint256(:public, :publicMintStart)\n uint256(:public, :publicMintEnd)\n uint256(:public, :publicMintPrice)\n bytes32(:public, :allowListMerkleRoot)\n uint256(:public, :allowListMaxPerAddress)\n uint256(:public, :allowListMintStart)\n uint256(:public, :allowListMintEnd)\n uint256(:public, :allowListMintPrice)\n uint256(:public, :perMintFee)\n address(:public, :feeTo)\n mapping(({ address: :uint256 }), :public, :publicNumberMinted)\n mapping(({ address: :uint256 }), :public, :allowListNumberMinted)\n constructor(name: :string, symbol: :string, maxSupply: :uint256, baseURI: :string, weth: :address, perMintFee: :uint256, feeTo: :address) {\n self.ERC721.constructor(name: name, symbol: symbol)\n self.Ownable.constructor(owner: msg.sender)\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n s.maxSupply=maxSupply\n s.baseURI=baseURI\n s.WETH=weth\n s.maxPerMint=25\n s.perMintFee=perMintFee\n s.feeTo=feeTo\n s.nextTokenId=1\n }\n function(:_handleMint, { to: :address, amount: :uint256, merkleProof: [:bytes32] }, :internal) {\n whenNotPaused!\n require(isMintActive, \"Mint is not active\")\n require(amount > 0, \"Amount must be positive\")\n require(s.maxSupply == 0 || s.totalSupply + amount <= s.maxSupply, \"Exceeded max supply\")\n require(amount <= s.maxPerMint, \"Exceeded max per mint\")\n isAllowListMint = merkleProof.length > 0 && isAllowListMintActive\n (numberMinted, mintPrice, maxPerAddress) = if isAllowListMint\n require(isOnAllowList(to, merkleProof), \"Not on allow list\")\n s.allowListNumberMinted[to] += amount\n [s.allowListNumberMinted[to], s.allowListMintPrice, s.allowListMaxPerAddress]\n else\n s.publicNumberMinted[to] += amount\n [s.publicNumberMinted[to], s.publicMintPrice, s.publicMaxPerAddress]\n end\n require(maxPerAddress == 0 || numberMinted <= maxPerAddress, \"Exceeded mint limit\")\n totalFee = s.perMintFee * amount\n if totalFee > 0 && s.feeTo != address(0)\n ERC20(s.WETH).transferFrom(msg.sender, s.feeTo, totalFee)\n end\n totalCost = mintPrice * amount\n if totalCost > 0\n require(s.WETH != address(0), \"WETH not set\")\n ERC20(s.WETH).transferFrom(msg.sender, address(this), totalCost)\n end\n initialId = s.nextTokenId\n s.nextTokenId += amount\n s.totalSupply += amount\n forLoop(condition: ->(i) {\n i < amount\n }, max_iterations: s.maxPerMint) { |i|\n _mint(to: to, id: initialId + i)\n }\n emit(:Minted, to: to, amount: amount, mintPrice: mintPrice, totalCost: totalCost, newTotalSupply: s.totalSupply, isPublic: !isAllowListMint)\n }\n function(:_isMintActive, { mintStart: :uint256, mintEnd: :uint256 }, :internal, :view, returns: :bool) {\n isNotMintedOut = s.maxSupply == 0 || s.totalSupply < s.maxSupply\n isOwner = s.owner == msg.sender\n isOrAfterStart = block.timestamp >= mintStart && mintStart > 0\n isBeforeEnd = block.timestamp < mintEnd || mintEnd == 0\n isNotMintedOut && isBeforeEnd && (isOwner || isOrAfterStart)\n }\n function(:isPublicMintActive, :public, :view, returns: :bool) {\n _isMintActive(mintStart: s.publicMintStart, mintEnd: s.publicMintEnd)\n }\n function(:isAllowListMintActive, :public, :view, returns: :bool) {\n _isMintActive(mintStart: s.allowListMintStart, mintEnd: s.allowListMintEnd)\n }\n function(:isMintActive, :public, :view, returns: :bool) {\n isPublicMintActive || isAllowListMintActive\n }\n function(:isOnAllowList, { wallet: :address, merkleProof: [:bytes32] }, :public, :view, returns: :bool) {\n self.MerkleProof.verify(merkleProof, s.allowListMerkleRoot, keccak256(abi.encodePacked(wallet)))\n }\n function(:tokenURI, { tokenId: :uint256 }, :public, :view, :override, returns: :string) {\n require(_exists(id: tokenId), \"URI query for nonexistent token\")\n if s.metadataRenderer != address(0)\n return IEditionMetadataRenderer01(s.metadataRenderer).tokenURI(tokenId)\n end\n if s.baseURI.length == 0\n return \"\"\n end\n if s.baseURI[s.baseURI.length - 1] != \"/\"\n return s.baseURI\n end\n s.baseURI + tokenId.toString\n }\n function(:contractURI, :public, :view, returns: :string) {\n if s.metadataRenderer == address(0)\n return \"\"\n end\n IEditionMetadataRenderer01(s.metadataRenderer).contractURI\n }\n function(:airdrop, { to: :address, amount: :uint256, merkleProof: [:bytes32] }, :public) {\n _handleMint(to: to, amount: amount, merkleProof: merkleProof)\n }\n function(:mint, { amount: :uint256, merkleProof: [:bytes32] }, :public) {\n _handleMint(to: msg.sender, amount: amount, merkleProof: merkleProof)\n }\n function(:setPublicMaxPerAddress, { publicMaxPerAddress: :uint256 }, :public) {\n onlyOwner!\n s.publicMaxPerAddress=publicMaxPerAddress\n emit(:PublicMaxPerAddressUpdated, publicMaxPerAddress: publicMaxPerAddress)\n }\n function(:setPublicMintStart, { publicMintStart: :uint256 }, :public) {\n onlyOwner!\n s.publicMintStart=publicMintStart\n emit(:PublicMintStartUpdated, publicMintStart: publicMintStart)\n }\n function(:setPublicMintEnd, { publicMintEnd: :uint256 }, :public) {\n onlyOwner!\n s.publicMintEnd=publicMintEnd\n emit(:PublicMintEndUpdated, publicMintEnd: publicMintEnd)\n }\n function(:setPublicMintPrice, { publicMintPrice: :uint256 }, :public) {\n onlyOwner!\n s.publicMintPrice=publicMintPrice\n emit(:PublicMintPriceUpdated, publicMintPrice: publicMintPrice)\n }\n function(:setAllowListMerkleRoot, { allowListMerkleRoot: :bytes32 }, :public) {\n onlyOwner!\n s.allowListMerkleRoot=allowListMerkleRoot\n emit(:AllowListMerkleRootUpdated, allowListMerkleRoot: allowListMerkleRoot)\n }\n function(:setAllowListMaxPerAddress, { allowListMaxPerAddress: :uint256 }, :public) {\n onlyOwner!\n s.allowListMaxPerAddress=allowListMaxPerAddress\n emit(:AllowListMaxPerAddressUpdated, allowListMaxPerAddress: allowListMaxPerAddress)\n }\n function(:setAllowListMintStart, { allowListMintStart: :uint256 }, :public) {\n onlyOwner!\n s.allowListMintStart=allowListMintStart\n emit(:AllowListMintStartUpdated, allowListMintStart: allowListMintStart)\n }\n function(:setAllowListMintEnd, { allowListMintEnd: :uint256 }, :public) {\n onlyOwner!\n s.allowListMintEnd=allowListMintEnd\n emit(:AllowListMintEndUpdated, allowListMintEnd: allowListMintEnd)\n }\n function(:setAllowListMintPrice, { allowListMintPrice: :uint256 }, :public) {\n onlyOwner!\n s.allowListMintPrice=allowListMintPrice\n emit(:AllowListMintPriceUpdated, allowListMintPrice: allowListMintPrice)\n }\n function(:setMaxSupply, { maxSupply: :uint256 }, :public) {\n onlyOwner!\n require(s.maxSupply == 0, \"Max supply already set\")\n require(maxSupply >= s.totalSupply, \"New max supply must be greater than total supply\")\n s.maxSupply=maxSupply\n emit(:MaxSupplyUpdated, maxSupply: maxSupply)\n }\n function(:setMetadataRenderer, { metadataRenderer: :address, data: :string }, :public) {\n onlyOwner!\n s.metadataRenderer=metadataRenderer\n if data.length > 0\n (success, _) = metadataRenderer.call(data)\n require(success, \"setMetadataRenderer failed\")\n end\n emit(:MetadataRendererUpdated, metadataRenderer: metadataRenderer)\n }\n function(:setPublicMintSettings, { publicMaxPerAddress: :uint256, publicMintStart: :uint256, publicMintEnd: :uint256, publicMintPrice: :uint256 }, :public) {\n setPublicMaxPerAddress(publicMaxPerAddress)\n setPublicMintStart(publicMintStart)\n setPublicMintEnd(publicMintEnd)\n setPublicMintPrice(publicMintPrice)\n }\n function(:setAllowListMintSettings, { allowListMerkleRoot: :bytes32, allowListMaxPerAddress: :uint256, allowListMintStart: :uint256, allowListMintEnd: :uint256, allowListMintPrice: :uint256 }, :public) {\n setAllowListMerkleRoot(allowListMerkleRoot)\n setAllowListMaxPerAddress(allowListMaxPerAddress)\n setAllowListMintStart(allowListMintStart)\n setAllowListMintEnd(allowListMintEnd)\n setAllowListMintPrice(allowListMintPrice)\n }\n function(:setBaseURI, { baseURI: :string }, :public) {\n onlyOwner!\n s.baseURI=baseURI\n emit(:BaseURIUpdated, baseURI: baseURI)\n }\n function(:burn, { tokenId: :uint256 }, :public) {\n require(isApprovedOrOwner(spender: msg.sender, id: tokenId), \"ERC721: msg.sender not authorized to burn id #{tokenId.toString}\")\n s.totalSupply -= 1\n _burn(tokenId)\n }\n function(:burnMultiple, { tokenIds: [:uint256] }, :public) {\n require(tokenIds.length > 0, \"No token ids provided\")\n require(tokenIds.length <= 20, \"Too many token ids provided\")\n forLoop(condition: ->(i) {\n i < tokenIds.length\n }, max_iterations: 20) { |i|\n burn(tokenIds[i])\n }\n }\n function(:pause, :public) {\n onlyOwner!\n _pause\n }\n function(:unpause, :public) {\n onlyOwner!\n _unpause\n }\n function(:withdrawWETH, :public, returns: :bool) {\n onlyOwner!\n amount = ERC20(s.WETH).balanceOf(address(this))\n ERC20(s.WETH).transfer(s.owner, amount)\n }\n function(:setDefaultRoyalty, { receiver: :address, feeNumerator: :uint96 }, :public) {\n onlyOwner!\n _setDefaultRoyalty(receiver: receiver, feeNumerator: feeNumerator)\n }\n function(:deleteDefaultRoyalty, :public) {\n onlyOwner!\n _deleteDefaultRoyalty\n }\n function(:setTokenRoyalty, { tokenId: :uint256, receiver: :address, feeNumerator: :uint96 }, :public) {\n onlyOwner!\n _setTokenRoyalty(tokenId: tokenId, receiver: receiver, feeNumerator: feeNumerator)\n }\n function(:deleteTokenRoyalty, { tokenId: :uint256 }, :public) {\n onlyOwner!\n _deleteTokenRoyalty(tokenId)\n }\n function(:setFeeTo, { feeTo: :address }, :public) {\n require(msg.sender == s.feeTo, \"Only feeTo can change feeTo\")\n s.feeTo=feeTo\n nil\n }\n}\n"}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x1673540243e793b0e77c038d4a88448eff524dce","function":"setFacetBuddyFactory","args":{"facetBuddyFactory":"0xbefa89a61c00730ff003854376148200b8f00e0a"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x1673540243e793b0e77c038d4a88448eff524dce","function":"upgrade","args":{"newHash":"0xdf13c05ccd7d54d7b9a8f3e2be83630c4d38d8bed6ce7e8f6a1a15466f3e9d58","newSource":"pragma(:rubidity, \"1.0.0\")\ncontract(:ERC20, abstract: true) {\n event(:Transfer, { from: :address, to: :address, amount: :uint256 })\n event(:Approval, { owner: :address, spender: :address, amount: :uint256 })\n string(:public, :name)\n string(:public, :symbol)\n uint8(:public, :decimals)\n uint256(:public, :totalSupply)\n mapping(({ address: :uint256 }), :public, :balanceOf)\n mapping(({ address: mapping(address: :uint256) }), :public, :allowance)\n constructor(name: :string, symbol: :string, decimals: :uint8) {\n s.name=name\n s.symbol=symbol\n s.decimals=decimals\n }\n function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n s.allowance[msg.sender][spender] = amount\n emit(:Approval, owner: msg.sender, spender: spender, amount: amount)\n return true\n }\n function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n require(s.balanceOf[msg.sender] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[msg.sender] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: msg.sender, to: to, amount: amount)\n return true\n }\n function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n allowed = s.allowance[from][msg.sender]\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n require(allowed \u003e= amount, \"Insufficient allowance\")\n s.allowance[from][msg.sender] = allowed - amount\n s.balanceOf[from] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: from, to: to, amount: amount)\n return true\n }\n function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {\n s.totalSupply += amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: address(0), to: to, amount: amount)\n }\n function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[from] -= amount\n s.totalSupply -= amount\n emit(:Transfer, from: from, to: address(0), amount: amount)\n }\n}\ncontract(:FacetBuddy) {\n event(:CallOnBehalfOfUser, { onBehalfOf: :address, addressToCall: :address, calldata: :string, initialAmount: :uint256, finalAmount: :uint256, resultSuccess: :bool, resultData: :string })\n address(:public, :factory)\n address(:public, :erc20Bridge)\n address(:public, :forUser)\n bool(:locked)\n constructor(erc20Bridge: :address, forUser: :address) {\n s.factory=msg.sender\n s.erc20Bridge=erc20Bridge\n s.forUser=forUser\n }\n function(:_makeCall, { addressToCall: :address, calldata: :string, revertOnFailure: :bool }, :internal) {\n require(addressToCall != address(this), \"Cannot call self\")\n require(!s.locked, \"No reentrancy allowed\")\n s.locked=true\n initialBalance = _balance\n _approve(addressToCall, initialBalance)\n (success, data) = addressToCall.call(calldata)\n require(success || !revertOnFailure, \"Call failed: (#{calldata})\")\n _approve(addressToCall, 0)\n finalBalance = _balance\n if finalBalance \u003e 0\n _transfer(s.forUser, finalBalance)\n end\n s.locked=false\n emit(:CallOnBehalfOfUser, onBehalfOf: s.forUser, addressToCall: addressToCall, calldata: calldata, initialAmount: initialBalance, finalAmount: finalBalance, resultSuccess: success, resultData: data)\n }\n function(:callForUser, { amountToSpend: :uint256, addressToCall: :address, calldata: :string }, :public) {\n require(msg.sender == s.forUser || msg.sender == s.factory, \"Only the user or factory can callForUser\")\n ERC20(s.erc20Bridge).transferFrom(s.forUser, address(this), amountToSpend)\n _makeCall(addressToCall, calldata, true)\n }\n function(:callFromBridge, { addressToCall: :address, calldata: :string }, :public) {\n require(msg.sender == s.erc20Bridge, \"Only the bridge can callFromBridge\")\n _makeCall(addressToCall, calldata, false)\n }\n function(:_balance, :internal, :view, returns: :uint256) {\n ERC20(s.erc20Bridge).balanceOf(address(this))\n }\n function(:_approve, { spender: :address, amount: :uint256 }, :internal, returns: :bool) {\n ERC20(s.erc20Bridge).approve(spender, amount)\n }\n function(:_transfer, { to: :address, amount: :uint256 }, :internal, returns: :bool) {\n ERC20(s.erc20Bridge).transfer(to, amount)\n }\n}\ncontract(:Upgradeable, abstract: true) {\n address(:public, :upgradeAdmin)\n event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })\n event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })\n constructor(upgradeAdmin: :address) {\n s.upgradeAdmin=upgradeAdmin\n }\n function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n s.upgradeAdmin=newUpgradeAdmin\n emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)\n }\n function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {\n upgrade(newHash: newHash, newSource: newSource)\n (success, data) = address(this).call(migrationCalldata)\n require(success, \"Migration failed\")\n }\n function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {\n currentHash = this.currentInitCodeHash\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n this.upgradeImplementation(newHash, newSource)\n emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)\n }\n}\ncontract(:FacetBuddyFactory, is: [:Upgradeable], upgradeable: true) {\n event(:BuddyCreated, { forUser: :address, buddy: :address })\n address(:public, :erc20Bridge)\n mapping(({ address: :address }), :public, :buddyForUser)\n mapping(({ address: :address }), :public, :userForBuddy)\n constructor(erc20Bridge: :address) {\n require(erc20Bridge != address(0), \"Invalid smart contract\")\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n s.erc20Bridge=erc20Bridge\n }\n function(:findOrCreateBuddy, { forUser: :address }, :public, returns: :address) {\n existingBuddy = s.buddyForUser[forUser]\n if existingBuddy != address(0)\n return existingBuddy\n end\n salt = keccak256(abi.encodePacked(forUser))\n buddy = new(FacetBuddy(s.erc20Bridge, forUser, { salt: salt }))\n require(s.userForBuddy[buddy] == address(0), \"Buddy already exists for user\")\n s.buddyForUser[forUser] = buddy\n s.userForBuddy[buddy] = forUser\n emit(:BuddyCreated, forUser: forUser, buddy: buddy)\n return buddy\n }\n function(:callBuddyForUser, { amountToSpend: :uint256, addressToCall: :address, calldata: :string }, :public) {\n buddy = findOrCreateBuddy(msg.sender)\n FacetBuddy(buddy).callForUser(amountToSpend: amountToSpend, addressToCall: addressToCall, calldata: calldata)\n }\n function(:predictBuddyAddress, { forUser: :address }, :public, :view, returns: :address) {\n return create2_address(salt: keccak256(abi.encodePacked(forUser)), deployer: address(this), contract_type: \"FacetBuddy\")\n }\n}\ncontract(:Ownable, abstract: true) {\n address(:public, :owner)\n event(:OwnershipTransferred, { previousOwner: :address, newOwner: :address })\n constructor(owner: :address) {\n s.owner=owner\n }\n function(:transferOwnership, { newOwner: :address }, :public) {\n onlyOwner!\n previousOwner = s.owner\n s.owner=newOwner\n emit(:OwnershipTransferred, previousOwner: previousOwner, newOwner: newOwner)\n }\n function(:onlyOwner!, :internal) {\n require(msg.sender == s.owner, \"msg.sender is not the owner\")\n }\n}\ncontract(:EtherBridge03, is: [:ERC20, :Upgradeable, :Ownable], upgradeable: true) {\n event(:BridgedIn, { to: :address, amount: :uint256 })\n event(:InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 })\n event(:WithdrawalComplete, { to: :address, amount: :uint256, withdrawalId: :bytes32 })\n address(:public, :trustedSmartContract)\n address(:public, :facetBuddyFactory)\n mapping(({ bytes32: :uint256 }), :public, :withdrawalIdAmount)\n mapping(({ address: :bytes32 }), :public, :userWithdrawalId)\n constructor(name: :string, symbol: :string, trustedSmartContract: :address) {\n require(trustedSmartContract != address(0), \"Invalid smart contract\")\n self.ERC20.constructor(name: name, symbol: symbol, decimals: 18)\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n self.Ownable.constructor(owner: msg.sender)\n s.trustedSmartContract=trustedSmartContract\n }\n function(:setFacetBuddyFactory, { facetBuddyFactory: :address }, :public) {\n onlyOwner!\n s.facetBuddyFactory=facetBuddyFactory\n nil\n }\n function(:bridgeIn, { to: :address, amount: :uint256 }, :public) {\n require(msg.sender == s.trustedSmartContract, \"Only the trusted smart contract can bridge in tokens\")\n _mint(to: to, amount: amount)\n emit(:BridgedIn, to: to, amount: amount)\n }\n function(:bridgeAndCall, { to: :address, amount: :uint256, addressToCall: :address, base64Calldata: :string }, :public) {\n if s.facetBuddyFactory == address(0)\n return bridgeIn(to: to, amount: amount)\n end\n buddy = FacetBuddyFactory(s.facetBuddyFactory).findOrCreateBuddy(to)\n bridgeIn(to: buddy, amount: amount)\n FacetBuddy(buddy).callFromBridge(addressToCall: addressToCall, calldata: base64Calldata.base64Decode)\n }\n function(:predictBuddyAddress, { forUser: :address }, :public, :view, returns: :address) {\n return FacetBuddyFactory(s.facetBuddyFactory).predictBuddyAddress(forUser)\n }\n function(:bridgeOut, { amount: :uint256 }, :public) {\n withdrawalId = tx.current_transaction_hash\n require(s.userWithdrawalId[msg.sender] == bytes32(0), \"Withdrawal pending\")\n require(s.withdrawalIdAmount[withdrawalId] == 0, \"Already bridged out\")\n require(amount \u003e 0, \"Invalid amount\")\n s.userWithdrawalId[msg.sender] = withdrawalId\n s.withdrawalIdAmount[withdrawalId] = amount\n _burn(from: msg.sender, amount: amount)\n emit(:InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId)\n }\n function(:markWithdrawalComplete, { to: :address, withdrawalId: :bytes32 }, :public) {\n require(msg.sender == s.trustedSmartContract, \"Only the trusted smart contract can mark withdrawals as complete\")\n require(s.userWithdrawalId[to] == withdrawalId, \"Withdrawal id not found\")\n amount = s.withdrawalIdAmount[withdrawalId]\n s.withdrawalIdAmount[withdrawalId] = 0\n s.userWithdrawalId[to] = bytes32(0)\n emit(:WithdrawalComplete, to: to, amount: amount, withdrawalId: withdrawalId)\n }\n}\n"}}}
data:application/vnd.facet.system+json;rule=esip6,{"op":"updateSupportedContracts","data":["0xdf13c05ccd7d54d7b9a8f3e2be83630c4d38d8bed6ce7e8f6a1a15466f3e9d58","0xa26bdad3c05ec5c4a0e234b5f755ca9cf7311dd857250a183b74a779e3c96ef8","0xb71fdafae3610cb8e74900b8e6d43163aaab54cc6e6c54ff5b7c7570a2dabe5c","0x070a0c891fd75ceaf600d45f7edfc18d02285a683a9db40bc8b3df0c54975859","0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","0xb5b742d755877bac6b80e2f0af4d97792fce2b2a58ff0ee2274b86eac91e977f","0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","0xb1b0ed1e4a8c9c9b0210f267137e368f782453e41f622fa8cf68296d04c84c88","0xe46dfedf0c0e9a0985d5151f5844bea96e5ac147cd9ddc7daa22a0899659d2f5","0x958b66f80d8d14e5c2129434bb8c78aabb60b5cfb7113224102e1a9a07c77ac5","0x2dce6b589dd5a5bedc5d9a91806a6cc5f16ae52c0f8dae730a886d7212db2dfd","0xd6c73897c5441fa221f1f0ebaee84241099b58f9cf51f6f4bcaf6bac4c29756d","0x45b224f1320c602a827823099dc4e7f596baf4227f919102a7f80523834edb02"]}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x1673540243e793b0e77c038d4a88448eff524dce","function":"transfer","args":{"amount":"31655309611470500000","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"982905753468278352399","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"1000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0x5d0dc4380fc8d501795aec7e7a908cb25c4131c6"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"58730024770828705486","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"1000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0x55ab0390a89fed8992e3affbf61d102490735e24"}}}
data:application/vnd.facet.system+json;rule=esip6,{"op":"updateSupportedContracts","data":["0xfd29ff1ad62a78d7c552167b1417f900e3095bfc603b84849e36488ae3017c14","0xf6165ed921e31487fd67838477eccf9c6e226d728e467f5bc8f8898864e290ee","0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","0xff325d0139ddecca5c76d9e6737d48d005c5842a76e79f545e850e03c502fa11","0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","0xbae85b82353ff68e9cee3036897d289b77c8393783829489b9ab3255c0158064","0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","0xb1b0ed1e4a8c9c9b0210f267137e368f782453e41f622fa8cf68296d04c84c88","0xe46dfedf0c0e9a0985d5151f5844bea96e5ac147cd9ddc7daa22a0899659d2f5","0x958b66f80d8d14e5c2129434bb8c78aabb60b5cfb7113224102e1a9a07c77ac5","0x2dce6b589dd5a5bedc5d9a91806a6cc5f16ae52c0f8dae730a886d7212db2dfd","0xd6c73897c5441fa221f1f0ebaee84241099b58f9cf51f6f4bcaf6bac4c29756d","0x45b224f1320c602a827823099dc4e7f596baf4227f919102a7f80523834edb02"]}
data:application/vnd.facet.system+json;rule=esip6,{"op":"updateSupportedContracts","data":["0xfd29ff1ad62a78d7c552167b1417f900e3095bfc603b84849e36488ae3017c14","0xf6165ed921e31487fd67838477eccf9c6e226d728e467f5bc8f8898864e290ee","0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","0xdd05de76d2ce547320b6ba23130b57651cf5a6bbdcd6c02854ce5c3b10439baa","0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","0xbae85b82353ff68e9cee3036897d289b77c8393783829489b9ab3255c0158064","0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","0xb1b0ed1e4a8c9c9b0210f267137e368f782453e41f622fa8cf68296d04c84c88","0xe46dfedf0c0e9a0985d5151f5844bea96e5ac147cd9ddc7daa22a0899659d2f5","0x958b66f80d8d14e5c2129434bb8c78aabb60b5cfb7113224102e1a9a07c77ac5","0x2dce6b589dd5a5bedc5d9a91806a6cc5f16ae52c0f8dae730a886d7212db2dfd","0xd6c73897c5441fa221f1f0ebaee84241099b58f9cf51f6f4bcaf6bac4c29756d","0x45b224f1320c602a827823099dc4e7f596baf4227f919102a7f80523834edb02"]}
UOdata:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xc59dec74518c6c86b90107c3644ac9daca149e70","function":"upgrade","args":{"newHash":"0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","newSource":"pragma(:rubidity, \"1.0.0\")\ncontract(:ERC20, abstract: true) {\n event(:Transfer, { from: :address, to: :address, amount: :uint256 })\n event(:Approval, { owner: :address, spender: :address, amount: :uint256 })\n string(:public, :name)\n string(:public, :symbol)\n uint8(:public, :decimals)\n uint256(:public, :totalSupply)\n mapping(({ address: :uint256 }), :public, :balanceOf)\n mapping(({ address: mapping(address: :uint256) }), :public, :allowance)\n constructor(name: :string, symbol: :string, decimals: :uint8) {\n s.name=name\n s.symbol=symbol\n s.decimals=decimals\n }\n function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n s.allowance[msg.sender][spender] = amount\n emit(:Approval, owner: msg.sender, spender: spender, amount: amount)\n return true\n }\n function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n require(s.balanceOf[msg.sender] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[msg.sender] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: msg.sender, to: to, amount: amount)\n return true\n }\n function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n allowed = s.allowance[from][msg.sender]\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n require(allowed \u003e= amount, \"Insufficient allowance\")\n s.allowance[from][msg.sender] = allowed - amount\n s.balanceOf[from] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: from, to: to, amount: amount)\n return true\n }\n function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {\n s.totalSupply += amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: address(0), to: to, amount: amount)\n }\n function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[from] -= amount\n s.totalSupply -= amount\n emit(:Transfer, from: from, to: address(0), amount: amount)\n }\n}\ncontract(:ERC2981, abstract: true) {\n event(:DefaultRoyaltyUpdated, { receiver: :address, feeNumerator: :uint96 })\n event(:TokenRoyaltyUpdated, { tokenId: :uint256, receiver: :address, feeNumerator: :uint96 })\n mapping(({ uint256: :address }), :internal, :_tokenIdToReceiver)\n mapping(({ uint256: :uint96 }), :internal, :_tokenIdToFeeNumerator)\n address(:internal, :_defaultRoyaltyReceiver)\n uint96(:internal, :_defaultFeeNumerator)\n function(:royaltyInfo, { tokenId: :uint256, salePrice: :uint256 }, :public, :view, :virtual, returns: { receiver: :address, royaltyAmount: :uint256 }) {\n receiver = s._tokenIdToReceiver[tokenId]\n feeNumerator = s._tokenIdToFeeNumerator[tokenId]\n if receiver == address(0)\n receiver = s._defaultRoyaltyReceiver\n feeNumerator = s._defaultFeeNumerator\n end\n royaltyAmount = (salePrice * feeNumerator).div(_feeDenominator)\n return { receiver: receiver, royaltyAmount: royaltyAmount }\n }\n function(:_setDefaultRoyalty, { receiver: :address, feeNumerator: :uint96 }, :internal, :virtual) {\n require(feeNumerator \u003c= _feeDenominator, \"ERC2981InvalidDefaultRoyalty\")\n require(receiver != address(0), \"ERC2981InvalidDefaultRoyaltyReceiver: address(0)\")\n s._defaultRoyaltyReceiver=receiver\n s._defaultFeeNumerator=feeNumerator\n emit(:DefaultRoyaltyUpdated, receiver: receiver, feeNumerator: feeNumerator)\n }\n function(:_deleteDefaultRoyalty, :internal, :virtual) {\n s._defaultRoyaltyReceiver=address(0)\n s._defaultFeeNumerator=0\n emit(:DefaultRoyaltyUpdated, receiver: address(0), feeNumerator: 0)\n }\n function(:_setTokenRoyalty, { tokenId: :uint256, receiver: :address, feeNumerator: :uint96 }, :internal, :virtual) {\n require(feeNumerator \u003c= _feeDenominator, \"ERC2981InvalidTokenRoyalty\")\n require(receiver != address(0), \"ERC2981InvalidTokenRoyaltyReceiver\")\n s._tokenIdToReceiver[tokenId] = receiver\n s._tokenIdToFeeNumerator[tokenId] = feeNumerator\n emit(:TokenRoyaltyUpdated, tokenId: tokenId, receiver: receiver, feeNumerator: feeNumerator)\n }\n function(:_deleteTokenRoyalty, { tokenId: :uint256 }, :internal, :virtual) {\n s._tokenIdToReceiver[tokenId] = address(0)\n s._tokenIdToFeeNumerator[tokenId] = 0\n emit(:TokenRoyaltyUpdated, tokenId: tokenId, receiver: address(0), feeNumerator: 0)\n }\n function(:_feeDenominator, :internal, :view, :virtual, returns: :uint96) {\n return 10000\n }\n function(:supportsERC2981, :public, :pure, :virtual, returns: :bool) {\n return true\n }\n}\ncontract(:ERC721, abstract: true) {\n event(:Transfer, { from: :address, to: :address, id: :uint256 })\n event(:Approval, { owner: :address, spender: :address, id: :uint256 })\n event(:ApprovalForAll, { owner: :address, operator: :address, approved: :bool })\n string(:public, :name)\n string(:public, :symbol)\n mapping(({ uint256: :address }), :internal, :_ownerOf)\n mapping(({ address: :uint256 }), :internal, :_balanceOf)\n mapping(({ uint256: :address }), :public, :getApproved)\n mapping(({ address: mapping(address: :bool) }), :public, :isApprovedForAll)\n constructor(name: :string, symbol: :string) {\n s.name=name\n s.symbol=symbol\n }\n function(:ownerOf, { id: :uint256 }, :public, :view, :virtual, returns: :address) {\n owner = s._ownerOf[id]\n require(owner != address(0), \"ERC721: owner query for nonexistent token\")\n return owner\n }\n function(:balanceOf, { owner: :address }, :public, :view, :virtual, returns: :uint256) {\n require(owner != address(0), \"ERC721: balance query for nonexistent owner\")\n return s._balanceOf[owner]\n }\n function(:approve, { spender: :address, id: :uint256 }, :public, :virtual) {\n owner = ownerOf(id)\n require(msg.sender == owner || s.isApprovedForAll[owner][msg.sender], \"ERC721: msg.sender not authorized to approve\")\n s.getApproved[id] = spender\n emit(:Approval, owner: owner, spender: spender, id: id)\n }\n function(:setApprovalForAll, { operator: :address, approved: :bool }, :public, :virtual) {\n s.isApprovedForAll[msg.sender][operator] = approved\n emit(:ApprovalForAll, owner: msg.sender, operator: operator, approved: approved)\n }\n function(:transferFrom, { from: :address, to: :address, id: :uint256 }, :public, :virtual) {\n require(from == ownerOf(id), \"ERC721: transfer of token that is not own\")\n require(to != address(0), \"ERC721: transfer to the zero address\")\n require(isApprovedOrOwner(spender: msg.sender, id: id), \"ERC721: msg.sender not authorized to call transferFrom\")\n s._balanceOf[from] -= 1\n s._balanceOf[to] += 1\n s._ownerOf[id] = to\n s.getApproved[id] = address(0)\n emit(:Transfer, from: from, to: to, id: id)\n }\n function(:isApprovedOrOwner, { spender: :address, id: :uint256 }, :public, :view, :virtual, returns: :bool) {\n owner = ownerOf(id)\n spender == owner || s.getApproved[id] == spender || s.isApprovedForAll[owner][spender]\n }\n function(:_exists, { id: :uint256 }, :internal, :view, :virtual, returns: :bool) {\n return s._ownerOf[id] != address(0)\n }\n function(:_mint, { to: :address, id: :uint256 }, :internal, :virtual) {\n require(to != address(0), \"ERC721: mint to the zero address\")\n require(s._ownerOf[id] == address(0), \"ERC721: token already minted\")\n s._balanceOf[to] += 1\n s._ownerOf[id] = to\n emit(:Transfer, from: address(0), to: to, id: id)\n }\n function(:_burn, { id: :uint256 }, :internal, :virtual) {\n owner = s._ownerOf[id]\n require(owner != address(0), \"ERC721: burn of nonexistent token\")\n s._balanceOf[owner] -= 1\n s._ownerOf[id] = address(0)\n s.getApproved[id] = address(0)\n emit(:Transfer, from: owner, to: address(0), id: id)\n }\n function(:tokenURI, { id: :uint256 }, :public, :view, :virtual, returns: :string) {\n }\n}\ncontract(:Ownable, abstract: true) {\n address(:public, :owner)\n event(:OwnershipTransferred, { previousOwner: :address, newOwner: :address })\n constructor(owner: :address) {\n s.owner=owner\n }\n function(:transferOwnership, { newOwner: :address }, :public) {\n onlyOwner!\n previousOwner = s.owner\n s.owner=newOwner\n emit(:OwnershipTransferred, previousOwner: previousOwner, newOwner: newOwner)\n }\n function(:onlyOwner!, :internal) {\n require(msg.sender == s.owner, \"msg.sender is not the owner\")\n }\n}\ncontract(:Pausable, abstract: true) {\n bool(:public, :paused)\n event(:Paused, { account: :address })\n event(:Unpaused, { account: :address })\n constructor(initialPauseState: :bool) {\n s.paused=initialPauseState\n }\n function(:_pause, :internal) {\n s.paused=true\n emit(:Paused, account: msg.sender)\n }\n function(:_unpause, :internal) {\n s.paused=false\n emit(:Unpaused, account: msg.sender)\n }\n function(:whenPaused!, :internal) {\n require(s.paused, \"Contract is not paused\")\n }\n function(:whenNotPaused!, :internal) {\n require(!s.paused, \"Contract is paused\")\n }\n}\ncontract(:Upgradeable, abstract: true) {\n address(:public, :upgradeAdmin)\n event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })\n event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })\n constructor(upgradeAdmin: :address) {\n s.upgradeAdmin=upgradeAdmin\n }\n function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n s.upgradeAdmin=newUpgradeAdmin\n emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)\n }\n function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {\n upgrade(newHash: newHash, newSource: newSource)\n (success, data) = address(this).call(migrationCalldata)\n require(success, \"Migration failed\")\n }\n function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {\n currentHash = this.currentInitCodeHash\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n this.upgradeImplementation(newHash, newSource)\n emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)\n }\n}\ncontract(:FacetPortV101, is: [:Upgradeable, :Ownable, :Pausable], upgradeable: true) {\n event(:OfferAccepted, { success: :bool, offerType: :string, offerer: :address, buyer: :address, seller: :address, recipient: :address, assetContract: :address, assetId: :uint256, considerationAmount: :uint256, considerationToken: :address, offerId: :bytes16 })\n event(:OfferCancelled, { offerer: :address, offerId: :bytes16 })\n event(:AllOffersOnAssetCancelledForUser, { offerType: :string, offerer: :address, assetContract: :address, assetId: :uint256 })\n event(:AllOffersCancelledForUser, { offerType: :string, offerer: :address })\n mapping(({ address: mapping(bytes16: :bool) }), :public, :userOfferCancellations)\n mapping(({ string: mapping(address: mapping(address: mapping(uint256: :uint256))) }), :public, :userOffersOnAssetValidAfterTime)\n mapping(({ string: mapping(address: :uint256) }), :public, :userOffersValidAfterTime)\n uint96(:feeBps)\n constructor(_feeBps: :uint96, _upgradeAdmin: :address, _owner: :address) {\n s.feeBps=_feeBps\n self.Upgradeable.constructor(upgradeAdmin: _upgradeAdmin)\n self.Ownable.constructor(owner: _owner)\n _pause\n }\n function(:setFeeBps, { _feeBps: :uint96 }, :external) {\n onlyOwner!\n s.feeBps=_feeBps\n }\n function(:pause, :public) {\n onlyOwner!\n _pause\n }\n function(:unpause, :public) {\n onlyOwner!\n _unpause\n }\n function(:acceptOfferWithSignature, { offerType: :string, offerId: :bytes16, offerer: :address, recipient: :address, assetContract: :address, assetId: :uint256, assetType: :string, assetAmount: :uint256, considerationToken: :address, considerationAmount: :uint256, startTime: :uint256, endTime: :uint256, signature: :bytes }, :external) {\n success = _acceptOfferWithSignature(offerType: offerType, offerId: offerId, offerer: offerer, recipient: recipient, assetContract: assetContract, assetId: assetId, assetType: assetType, assetAmount: assetAmount, considerationToken: considerationToken, considerationAmount: considerationAmount, startTime: startTime, endTime: endTime, signature: signature)\n require(success, \"Offer was not successfully accepted\")\n }\n function(:acceptMultipleOffersWithSignatures, { offerTypes: [:string], offerIds: [:bytes16], offerers: [:address], recipients: [:address], assetContracts: [:address], assetIds: [:uint256], assetTypes: [:string], assetAmounts: [:uint256], considerationTokens: [:address], considerationAmounts: [:uint256], startTimes: [:uint256], endTimes: [:uint256], signatures: [:bytes] }, :external) {\n require(offerIds.length == offerers.length, \"Offer ID and offerer arrays must be the same length\")\n require(offerIds.length == offerTypes.length, \"Offer ID and offer types arrays must be the same length\")\n require(offerIds.length == assetContracts.length, \"Offer ID and asset contracts arrays must be the same length\")\n require(offerIds.length == assetIds.length, \"Offer ID and asset IDs arrays must be the same length\")\n require(offerIds.length == assetTypes.length, \"Offer ID and assetTypes arrays must be the same length\")\n require(offerIds.length == assetAmounts.length, \"Offer ID and assetAmounts arrays must be the same length\")\n require(offerIds.length == considerationTokens.length, \"Offer ID and consideration tokens arrays must be the same length\")\n require(offerIds.length == considerationAmounts.length, \"Offer ID and consideration amounts arrays must be the same length\")\n require(offerIds.length == startTimes.length, \"Offer ID and start times arrays must be the same length\")\n require(offerIds.length == endTimes.length, \"Offer ID and end times arrays must be the same length\")\n require(offerIds.length == signatures.length, \"Offer ID and signatures arrays must be the same length\")\n require(offerIds.length == recipients.length, \"Offer ID and recipients arrays must be the same length\")\n require(offerIds.length \u003c= 20, \"Cannot accept more than 20 offers at a time\")\n atLeastOneSuccess = false\n forLoop(condition: -\u003e(i) {\n i \u003c offerIds.length\n }) { |i|\n success = _acceptOfferWithSignature(offerType: offerTypes[i], offerId: offerIds[i], offerer: offerers[i], recipient: recipients[i], assetContract: assetContracts[i], assetId: assetIds[i], assetType: assetTypes[i], assetAmount: assetAmounts[i], considerationToken: considerationTokens[i], considerationAmount: considerationAmounts[i], startTime: startTimes[i], endTime: endTimes[i], signature: signatures[i])\n if success\n atLeastOneSuccess = true\n end\n }\n require(atLeastOneSuccess, \"No offers were successfully accepted\")\n }\n function(:_acceptOfferWithSignature, { offerType: :string, offerId: :bytes16, offerer: :address, recipient: :address, assetContract: :address, assetId: :uint256, assetType: :string, assetAmount: :uint256, considerationToken: :address, considerationAmount: :uint256, startTime: :uint256, endTime: :uint256, signature: :bytes }, :internal, returns: :bool) {\n whenNotPaused!\n signatureValid = signature.verifyTypedDataSignature({ Offer: [{ name: \"offerType\", type: \"string\" }, { name: \"offerId\", type: \"bytes16\" }, { name: \"offerer\", type: \"address\" }, { name: \"assetContract\", type: \"address\" }, { name: \"assetId\", type: \"uint256\" }, { name: \"assetType\", type: \"string\" }, { name: \"assetAmount\", type: \"uint256\" }, { name: \"considerationToken\", type: \"address\" }, { name: \"considerationAmount\", type: \"uint256\" }, { name: \"startTime\", type: \"uint256\" }, { name: \"endTime\", type: \"uint256\" }] }, { offerType: offerType, offerId: offerId, offerer: offerer, assetContract: assetContract, assetId: assetId, assetType: assetType, assetAmount: assetAmount, considerationToken: considerationToken, considerationAmount: considerationAmount, startTime: startTime, endTime: endTime }, verifyingContract: address(this), domainName: \"FacetPort\", domainVersion: \"1\", signer: offerer)\n require(signatureValid, \"Invalid signature\")\n require(!s.userOfferCancellations[offerer][offerId], \"Offer cancelled\")\n require(offerType == \"Listing\" || offerType == \"Bid\", \"Invalid offer type\")\n require(assetType == \"ERC721\" \u0026\u0026 assetAmount == 1, \"Only ERC721 assets are supported\")\n require(block.timestamp \u003e= startTime, \"Current time is before the start time\")\n require(block.timestamp \u003c endTime, \"Current time is after the end time\")\n require(startTime \u003e s.userOffersOnAssetValidAfterTime[offerType][offerer][assetContract][assetId], \"Start time is before the offerer's valid after time\")\n require(startTime \u003e s.userOffersValidAfterTime[offerType][offerer], \"Start time is before the valid after time for the offerer\")\n (buyer, seller) = if offerType == \"Bid\"\n [offerer, msg.sender]\n else\n [msg.sender, offerer]\n end\n transferSucceeded = _payRoyaltiesAndTransfer(assetContract: assetContract, assetId: assetId, seller: seller, buyer: buyer, recipient: recipient, considerationAmount: considerationAmount, considerationToken: considerationToken)\n emit(:OfferAccepted, { success: transferSucceeded, offerType: offerType, offerer: offerer, buyer: buyer, seller: seller, recipient: recipient, assetContract: assetContract, assetId: assetId, considerationAmount: considerationAmount, considerationToken: considerationToken, offerId: offerId })\n transferSucceeded\n }\n function(:_payRoyaltiesAndTransfer, { assetContract: :address, assetId: :uint256, seller: :address, buyer: :address, recipient: :address, considerationAmount: :uint256, considerationToken: :address }, :internal, returns: :bool) {\n require(recipient == address(0) || msg.sender == buyer, \"Only buyer can add recipient\")\n currentOwner = ERC721(assetContract).ownerOf(assetId)\n unless currentOwner == seller\n return false\n end\n (success, data) = assetContract.call(function: \"supportsERC2981\")\n royaltyAmount = 0\n if success \u0026\u0026 data == \"true\"\n (receiver, royaltyAmount) = ERC2981(assetContract).royaltyInfo(tokenId: assetId, salePrice: considerationAmount)\n if receiver == address(0)\n royaltyAmount = 0\n end\n if royaltyAmount \u003e 0\n ERC20(considerationToken).transferFrom(from: buyer, to: receiver, amount: royaltyAmount)\n end\n end\n marketplaceFee = computeFee(considerationAmount)\n sellerAmount = considerationAmount - royaltyAmount - marketplaceFee\n if sellerAmount \u003e 0\n ERC20(considerationToken).transferFrom(from: buyer, to: seller, amount: sellerAmount)\n end\n if marketplaceFee \u003e 0\n ERC20(considerationToken).transferFrom(from: buyer, to: owner, amount: marketplaceFee)\n end\n _transferNFT(assetContract: assetContract, assetId: assetId, recipient: if recipient == address(0)\n buyer\n else\n recipient\n end, from: seller)\n return true\n }\n function(:transferNFTs, { assetContracts: [:address], assetIds: [:uint256], recipients: [:address] }, :external) {\n require(assetContracts.length == assetIds.length, \"Asset contracts and asset IDs must be the same length\")\n require(assetContracts.length == recipients.length, \"Asset contracts and recipients must be the same length\")\n require(assetIds.length \u003c= 20, \"Cannot transfer more than 20 NFTs at a time\")\n forLoop(condition: -\u003e(i) {\n i \u003c recipients.length\n }) { |i|\n _transferNFT(assetContract: assetContracts[i], assetId: assetIds[i], recipient: recipients[i], from: msg.sender)\n }\n }\n function(:_transferNFT, { assetContract: :address, assetId: :uint256, recipient: :address, from: :address }, :internal) {\n whenNotPaused!\n ERC721(assetContract).transferFrom(from: from, to: recipient, id: assetId)\n s.userOffersOnAssetValidAfterTime[\"Listing\"][from][assetContract][assetId] = block.timestamp\n s.userOffersOnAssetValidAfterTime[\"Bid\"][recipient][assetContract][assetId] = block.timestamp\n nil\n }\n function(:cancelOffer, { offerId: :bytes16 }, :external) {\n s.userOfferCancellations[msg.sender][offerId] = true\n emit(:OfferCancelled, offerer: msg.sender, offerId: offerId)\n }\n function(:cancelAllOffersForAsset, { offerType: :string, assetContract: :address, assetId: :uint256 }, :external) {\n require(offerType == \"Listing\" || offerType == \"Bid\", \"Invalid offer type\")\n s.userOffersOnAssetValidAfterTime[offerType][msg.sender][assetContract][assetId] = block.timestamp\n emit(:AllOffersOnAssetCancelledForUser, offerType: offerType, offerer: msg.sender, assetContract: assetContract, assetId: assetId)\n }\n function(:cancelAllOffersOfUser, { offerType: :string }, :external) {\n require(offerType == \"Listing\" || offerType == \"Bid\", \"Invalid offer type\")\n s.userOffersValidAfterTime[offerType][msg.sender] = block.timestamp\n emit(:AllOffersCancelledForUser, offerType: offerType, offerer: msg.sender)\n }\n function(:computeFee, { amount: :uint256 }, :public, :view, returns: :uint256) {\n return (amount * s.feeBps).div(10000)\n }\n}\n"}}}
data:application/vnd.facet.system+json;rule=esip6,{"op":"updateSupportedContracts","data":["0xfd29ff1ad62a78d7c552167b1417f900e3095bfc603b84849e36488ae3017c14","0xf6165ed921e31487fd67838477eccf9c6e226d728e467f5bc8f8898864e290ee","0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","0x0974b723d3a7c688be3a60ea523f902d56b4eb825eda09306925588f6d36c5f8","0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","0xbae85b82353ff68e9cee3036897d289b77c8393783829489b9ab3255c0158064","0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","0xb1b0ed1e4a8c9c9b0210f267137e368f782453e41f622fa8cf68296d04c84c88","0xe46dfedf0c0e9a0985d5151f5844bea96e5ac147cd9ddc7daa22a0899659d2f5","0x958b66f80d8d14e5c2129434bb8c78aabb60b5cfb7113224102e1a9a07c77ac5","0x2dce6b589dd5a5bedc5d9a91806a6cc5f16ae52c0f8dae730a886d7212db2dfd","0xd6c73897c5441fa221f1f0ebaee84241099b58f9cf51f6f4bcaf6bac4c29756d","0x45b224f1320c602a827823099dc4e7f596baf4227f919102a7f80523834edb02"]}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"create","data":{"init_code_hash":"0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","args":{},"source_code":"pragma(:rubidity, \"1.0.0\")\ncontract(:INFTCollection01, abstract: true) {\n function(:owner, :external, :view, returns: :address)\n}\ncontract(:Upgradeable, abstract: true) {\n address(:public, :upgradeAdmin)\n event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })\n event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })\n constructor(upgradeAdmin: :address) {\n s.upgradeAdmin=upgradeAdmin\n }\n function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n s.upgradeAdmin=newUpgradeAdmin\n emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)\n }\n function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {\n upgrade(newHash: newHash, newSource: newSource)\n (success, data) = address(this).call(migrationCalldata)\n require(success, \"Migration failed\")\n }\n function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {\n currentHash = this.currentInitCodeHash\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n this.upgradeImplementation(newHash, newSource)\n emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)\n }\n}\ncontract(:EditionMetadataRenderer01, is: :Upgradeable, upgradeable: true) {\n struct(:TokenEditionInfo) {\n string(:name)\n string(:description)\n string(:imageURI)\n string(:animationURI)\n }\n event(:MediaURIsUpdated, { target: :address, sender: :address, imageURI: :string, animationURI: :string })\n event(:EditionInitialized, { target: :address, description: :string, imageURI: :string, animationURI: :string, name: :string })\n event(:DescriptionUpdated, { target: :address, sender: :address, newDescription: :string })\n mapping(({ address: :TokenEditionInfo }), :public, :tokenInfos)\n constructor {\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n }\n function(:requireSenderAdmin, { target: :address }, :internal, :pure) {\n require(target == msg.sender || INFTCollection01(target).owner == msg.sender, \"Admin access only\")\n }\n function(:updateMediaURIs, { target: :address, imageURI: :string, animationURI: :string }, :external) {\n requireSenderAdmin(target)\n s.tokenInfos[target].imageURI=imageURI\n s.tokenInfos[target].animationURI=animationURI\n emit(:MediaURIsUpdated, target: target, sender: msg.sender, imageURI: imageURI, animationURI: animationURI)\n }\n function(:updateDescription, { target: :address, newDescription: :string }, :external) {\n requireSenderAdmin(target)\n s.tokenInfos[target].description=newDescription\n emit(:DescriptionUpdated, target: target, sender: msg.sender, newDescription: newDescription)\n }\n function(:initializeWithData, { info: :TokenEditionInfo }, :external) {\n s.tokenInfos[msg.sender] = info\n emit(:EditionInitialized, target: msg.sender, description: info.description, imageURI: info.imageURI, animationURI: info.animationURI, name: info.name)\n }\n function(:contractURI, :external, :view, returns: :string) {\n target = msg.sender\n editionInfo = s.tokenInfos[target]\n encodeContractURIJSON(editionInfo.name, editionInfo.description, editionInfo.imageURI, editionInfo.animationURI)\n }\n function(:tokenURI, { tokenId: :uint256 }, :external, :view, returns: :string) {\n target = msg.sender\n info = s.tokenInfos[target]\n createMetadataEdition(info.name, info.description, info.imageURI, info.animationURI, tokenId)\n }\n function(:createMetadataEdition, { name: :string, description: :string, imageURI: :string, animationURI: :string, tokenOfEdition: :uint256 }, :internal, :pure, returns: :string) {\n _tokenMediaData = tokenMediaData(imageURI, animationURI)\n json = createMetadataJSON(name, description, _tokenMediaData, tokenOfEdition)\n encodeMetadataJSON(json)\n }\n function(:encodeContractURIJSON, { name: :string, description: :string, imageURI: :string, animationURI: :string }, :internal, :pure, returns: :string) {\n imageSpace = if imageURI.length > 0\n \"\\\", \\\"image\\\": \\\"\" + imageURI\n else\n \"\"\n end\n animationSpace = if animationURI.length > 0\n \"\\\", \\\"animation_url\\\": \\\"\" + animationURI\n else\n \"\"\n end\n encodeMetadataJSON(\"{\\\"name\\\": \\\"\" + name + \"\\\", \\\"description\\\": \\\"\" + description + imageSpace + animationSpace + \"\\\"}\")\n }\n function(:createMetadataJSON, { name: :string, description: :string, mediaData: :string, tokenOfEdition: :uint256 }, :internal, :pure, returns: :string) {\n \"{\\\"name\\\": \\\"\" + name + \" \" + tokenOfEdition.toString + \"\\\", \\\"description\\\": \\\"\" + description + \"\\\", \\\"\" + mediaData + \"properties\\\": {\\\"number\\\": \" + tokenOfEdition.toString + \", \\\"name\\\": \\\"\" + name + \"\\\"}}\"\n }\n function(:encodeMetadataJSON, { json: :string }, :internal, :pure, returns: :string) {\n \"data:application/json;base64,\" + json.base64Encode\n }\n function(:tokenMediaData, { imageUrl: :string, animationUrl: :string }, :internal, :pure, returns: :string) {\n hasImage = imageUrl.length > 0\n hasAnimation = animationUrl.length > 0\n if hasImage && hasAnimation\n return \"image\\\": \\\"\" + imageUrl + \"\\\", \\\"animation_url\\\": \\\"\" + animationUrl + \"\\\", \\\"\"\n else\n if hasImage\n return \"image\\\": \\\"\" + imageUrl + \"\\\", \\\"\"\n else\n if hasAnimation\n return \"animation_url\\\": \\\"\" + animationUrl + \"\\\", \\\"\"\n end\n end\n end\n \"\"\n }\n}\n"}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x1673540243e793b0e77c038d4a88448eff524dce","function":"upgradeAndCall","args":{"newHash":"0xf6165ed921e31487fd67838477eccf9c6e226d728e467f5bc8f8898864e290ee","newSource":"pragma(:rubidity, \"1.0.0\")\ncontract(:ERC20, abstract: true) {\n event(:Transfer, { from: :address, to: :address, amount: :uint256 })\n event(:Approval, { owner: :address, spender: :address, amount: :uint256 })\n string(:public, :name)\n string(:public, :symbol)\n uint8(:public, :decimals)\n uint256(:public, :totalSupply)\n mapping(({ address: :uint256 }), :public, :balanceOf)\n mapping(({ address: mapping(address: :uint256) }), :public, :allowance)\n constructor(name: :string, symbol: :string, decimals: :uint8) {\n s.name=name\n s.symbol=symbol\n s.decimals=decimals\n }\n function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n s.allowance[msg.sender][spender] = amount\n emit(:Approval, owner: msg.sender, spender: spender, amount: amount)\n return true\n }\n function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n require(s.balanceOf[msg.sender] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[msg.sender] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: msg.sender, to: to, amount: amount)\n return true\n }\n function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {\n allowed = s.allowance[from][msg.sender]\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n require(allowed \u003e= amount, \"Insufficient allowance\")\n s.allowance[from][msg.sender] = allowed - amount\n s.balanceOf[from] -= amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: from, to: to, amount: amount)\n return true\n }\n function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {\n s.totalSupply += amount\n s.balanceOf[to] += amount\n emit(:Transfer, from: address(0), to: to, amount: amount)\n }\n function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {\n require(s.balanceOf[from] \u003e= amount, \"Insufficient balance\")\n s.balanceOf[from] -= amount\n s.totalSupply -= amount\n emit(:Transfer, from: from, to: address(0), amount: amount)\n }\n}\ncontract(:Ownable, abstract: true) {\n address(:public, :owner)\n event(:OwnershipTransferred, { previousOwner: :address, newOwner: :address })\n constructor(owner: :address) {\n s.owner=owner\n }\n function(:transferOwnership, { newOwner: :address }, :public) {\n onlyOwner!\n previousOwner = s.owner\n s.owner=newOwner\n emit(:OwnershipTransferred, previousOwner: previousOwner, newOwner: newOwner)\n }\n function(:onlyOwner!, :internal) {\n require(msg.sender == s.owner, \"msg.sender is not the owner\")\n }\n}\ncontract(:Upgradeable, abstract: true) {\n address(:public, :upgradeAdmin)\n event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })\n event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })\n constructor(upgradeAdmin: :address) {\n s.upgradeAdmin=upgradeAdmin\n }\n function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n s.upgradeAdmin=newUpgradeAdmin\n emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)\n }\n function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {\n upgrade(newHash: newHash, newSource: newSource)\n (success, data) = address(this).call(migrationCalldata)\n require(success, \"Migration failed\")\n }\n function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {\n currentHash = this.currentInitCodeHash\n require(msg.sender == s.upgradeAdmin, \"NOT_AUTHORIZED\")\n this.upgradeImplementation(newHash, newSource)\n emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)\n }\n}\ncontract(:BridgeAndCallHelper, is: [:Upgradeable, :Ownable], upgradeable: true) {\n event(:CallFromBridge, { bridgingUser: :address, addressToCall: :address, calldata: :string, initialAmount: :uint256, finalAmount: :uint256, feeAmount: :uint256, resultStatus: :bool, resultData: :string })\n event(:BridgeUpdated, { newBridge: :address })\n event(:FeeUpdated, { newFee: :uint256 })\n address(:public, :bridge)\n uint256(:public, :fee)\n bool(:locked)\n constructor(bridge: :address, fee: :uint256, owner: :address) {\n self.Ownable.constructor(owner: owner)\n self.Upgradeable.constructor(upgradeAdmin: owner)\n s.bridge=bridge\n s.fee=fee\n }\n function(:setBridge, { newBridge: :address }, :public) {\n onlyOwner!\n s.bridge=newBridge\n emit(:BridgeUpdated, newBridge: newBridge)\n }\n function(:setFee, { newFee: :uint256 }, :public) {\n onlyOwner!\n s.fee=newFee\n emit(:FeeUpdated, newFee: newFee)\n }\n function(:callFromBridge, { bridgingUser: :address, addressToCall: :address, base64Calldata: :string }, :public) {\n require(msg.sender == s.bridge, \"Only the bridge can callFromBridge\")\n require(addressToCall != address(this), \"Cannot call self\")\n require(!s.locked, \"No reentrancy allowed\")\n s.locked=true\n calldata = base64Calldata.base64Decode\n initialBalance = _balance\n calculatedFee = if initialBalance \u003c s.fee\n initialBalance\n else\n s.fee\n end\n if calculatedFee \u003e 0\n _transfer(s.owner, calculatedFee)\n end\n _approve(addressToCall, initialBalance - calculatedFee)\n (success, data) = addressToCall.call(calldata)\n _approve(addressToCall, 0)\n finalBalance = _balance\n if finalBalance \u003e 0\n _transfer(bridgingUser, finalBalance)\n end\n s.locked=false\n emit(:CallFromBridge, bridgingUser: bridgingUser, addressToCall: addressToCall, calldata: calldata, initialAmount: initialBalance, finalAmount: finalBalance, feeAmount: calculatedFee, resultStatus: success, resultData: data)\n }\n function(:_balance, :internal, :view, returns: :uint256) {\n ERC20(s.bridge).balanceOf(address(this))\n }\n function(:_approve, { spender: :address, amount: :uint256 }, :internal, returns: :bool) {\n ERC20(s.bridge).approve(spender, amount)\n }\n function(:_transfer, { to: :address, amount: :uint256 }, :internal, returns: :bool) {\n ERC20(s.bridge).transfer(to, amount)\n }\n}\ncontract(:EtherBridge02, is: [:ERC20, :Upgradeable, :Ownable], upgradeable: true) {\n event(:BridgedIn, { to: :address, amount: :uint256 })\n event(:InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 })\n event(:WithdrawalComplete, { to: :address, amount: :uint256, withdrawalId: :bytes32 })\n address(:public, :trustedSmartContract)\n address(:public, :bridgeAndCallHelper)\n mapping(({ bytes32: :uint256 }), :public, :withdrawalIdAmount)\n mapping(({ address: :bytes32 }), :public, :userWithdrawalId)\n constructor(name: :string, symbol: :string, trustedSmartContract: :address, bridgeAndCallHelper: :address) {\n require(trustedSmartContract != address(0), \"Invalid smart contract\")\n self.ERC20.constructor(name: name, symbol: symbol, decimals: 18)\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n self.Ownable.constructor(owner: msg.sender)\n s.trustedSmartContract=trustedSmartContract\n s.bridgeAndCallHelper=bridgeAndCallHelper\n }\n function(:onUpgrade, { owner: :address, bridgeAndCallHelper: :address }, :public) {\n require(msg.sender == address(this), \"Only the contract itself can upgrade\")\n s.owner=owner\n s.bridgeAndCallHelper=bridgeAndCallHelper\n return nil\n }\n function(:setBridgeAndCallHelper, { bridgeAndCallHelper: :address }, :public) {\n onlyOwner!\n s.bridgeAndCallHelper=bridgeAndCallHelper\n nil\n }\n function(:bridgeIn, { to: :address, amount: :uint256 }, :public) {\n require(msg.sender == s.trustedSmartContract, \"Only the trusted smart contract can bridge in tokens\")\n _mint(to: to, amount: amount)\n emit(:BridgedIn, to: to, amount: amount)\n }\n function(:bridgeAndCall, { to: :address, amount: :uint256, addressToCall: :address, base64Calldata: :string }, :public) {\n if s.bridgeAndCallHelper == address(0)\n return bridgeIn(to: to, amount: amount)\n end\n bridgeIn(to: s.bridgeAndCallHelper, amount: amount)\n BridgeAndCallHelper(s.bridgeAndCallHelper).callFromBridge(bridgingUser: to, addressToCall: addressToCall, base64Calldata: base64Calldata)\n }\n function(:bridgeOut, { amount: :uint256 }, :public) {\n withdrawalId = tx.current_transaction_hash\n require(s.userWithdrawalId[msg.sender] == bytes32(0), \"Withdrawal pending\")\n require(s.withdrawalIdAmount[withdrawalId] == 0, \"Already bridged out\")\n require(amount \u003e 0, \"Invalid amount\")\n s.userWithdrawalId[msg.sender] = withdrawalId\n s.withdrawalIdAmount[withdrawalId] = amount\n _burn(from: msg.sender, amount: amount)\n emit(:InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId)\n }\n function(:markWithdrawalComplete, { to: :address, withdrawalId: :bytes32 }, :public) {\n require(msg.sender == s.trustedSmartContract, \"Only the trusted smart contract can mark withdrawals as complete\")\n require(s.userWithdrawalId[to] == withdrawalId, \"Withdrawal id not found\")\n amount = s.withdrawalIdAmount[withdrawalId]\n s.withdrawalIdAmount[withdrawalId] = 0\n s.userWithdrawalId[to] = bytes32(0)\n emit(:WithdrawalComplete, to: to, amount: amount, withdrawalId: withdrawalId)\n }\n}\n","migrationCalldata":"{\"function\":\"onUpgrade\",\"args\":{\"owner\":\"0xb2b01decb6cd36e7396b78d3744482627f22c525\",\"bridgeAndCallHelper\":\"0x6a838d118a429d6e6debdd7805cfe66146e4d171\"}}"}}}
data:application/vnd.facet.system+json;rule=esip6,{"op":"updateSupportedContracts","data":["0xfd29ff1ad62a78d7c552167b1417f900e3095bfc603b84849e36488ae3017c14","0xf6165ed921e31487fd67838477eccf9c6e226d728e467f5bc8f8898864e290ee","0xd7ecfb5c3eb58b7875a7c70799632006a0c00e4e002aea6b1e03809442f763f8","0x0974b723d3a7c688be3a60ea523f902d56b4eb825eda09306925588f6d36c5f8","0xee18008875b9e2ecadebb7566928a6a853a23f15c2393221f6a9db8d81fd5670","0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","0xb1b0ed1e4a8c9c9b0210f267137e368f782453e41f622fa8cf68296d04c84c88","0xe46dfedf0c0e9a0985d5151f5844bea96e5ac147cd9ddc7daa22a0899659d2f5","0x958b66f80d8d14e5c2129434bb8c78aabb60b5cfb7113224102e1a9a07c77ac5","0x2dce6b589dd5a5bedc5d9a91806a6cc5f16ae52c0f8dae730a886d7212db2dfd","0xd6c73897c5441fa221f1f0ebaee84241099b58f9cf51f6f4bcaf6bac4c29756d","0x45b224f1320c602a827823099dc4e7f596baf4227f919102a7f80523834edb02"]}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x1673540243e793b0e77c038d4a88448eff524dce","function":"transfer","args":{"amount":"2299386609589006374","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"2400863312624837877638","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"1000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0x5d0dc4380fc8d501795aec7e7a908cb25c4131c6"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"removeLiquidity","args":{"liquidity":"81198601388874268475","to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7","deadline":"1000000000000000000","amountAMin":"0","amountBMin":"0","tokenA":"0x1673540243e793b0e77c038d4a88448eff524dce","tokenB":"0x55ab0390a89fed8992e3affbf61d102490735e24"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xf29e6e319ac4ce8c100cfc02b1702eb3d275029e","function":"withdrawFees","args":{"to":"0xD66Cb98865181a890ffee5654fAe1D6b4D1827a7"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0xfcb66afc2fc75056a8b45947d881a1d7b023693d","function":"upgradeAndCall","args":{"newHash":"0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","newSource":"","migrationCalldata":"{\"function\":\"onUpgrade\",\"args\":{\"owner\":\"0xb2B01DeCb6cd36E7396b78D3744482627F22C525\",\"bridgeLimit\":100}}"}}}
data:application/vnd.facet.tx+json;rule=esip6,{"op":"call","data":{"to":"0x55ab0390a89fed8992e3affbf61d102490735e24","function":"upgradeAndCall","args":{"newHash":"0x6c5eee22f9574d847b4d90833da27228c6567cee2e004d4ccbb6a34011ab66e4","newSource":"","migrationCalldata":"{\"function\":\"onUpgrade\",\"args\":{\"owner\":\"0xb2B01DeCb6cd36E7396b78D3744482627F22C525\",\"bridgeLimit\":100}}"}}}
1-50 of 77