0xd66cb988…27a7sent to0x00000000…ace7·#19,561,604·view on Etherscan
data:application/vnd.facet.tx+json;rule=esip6,{"op":"create","data":{"init_code_hash":"0x9022ced2f52aee8b28119f0490767a6e0b80b492642364382e609b6e84d85ce0","args":{"trustedSmartContract":"0x00000000000001a49E2dac26e7a55EFB3F8fc0B6"},"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(: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(:ERC20Bridge, is: [:ERC20, :Upgradeable], 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, :factory)\n address(:public, :tokenSmartContract)\n address(:public, :trustedSmartContract)\n mapping(({ bytes32: :uint256 }), :public, :withdrawalIdAmount)\n mapping(({ address: :bytes32 }), :public, :userWithdrawalId)\n constructor(tokenSmartContract: :address, trustedSmartContract: :address, name: :string, symbol: :string, decimals: :uint8) {\n self.ERC20.constructor(name: name, symbol: symbol, decimals: decimals)\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n s.tokenSmartContract=tokenSmartContract\n s.trustedSmartContract=trustedSmartContract\n s.factory=msg.sender\n }\n function(:onlyFactory!, :internal) {\n require(msg.sender == s.factory, \"Only the factory can call this function\")\n }\n function(:bridgeIn, { to: :address, amount: :uint256 }, :public) {\n onlyFactory!\n _mint(to: to, amount: amount)\n emit(:BridgedIn, to: to, amount: amount)\n }\n function(:bridgeOut, { from: :address, amount: :uint256 }, :public) {\n onlyFactory!\n withdrawalId = tx.current_transaction_hash\n require(s.userWithdrawalId[from] == bytes32(0), \"Withdrawal pending\")\n require(s.withdrawalIdAmount[withdrawalId] == 0, \"Already bridged out\")\n require(amount > 0, \"Invalid amount\")\n s.userWithdrawalId[from] = withdrawalId\n s.withdrawalIdAmount[withdrawalId] = amount\n _burn(from: from, amount: amount)\n emit(:InitiateWithdrawal, from: from, amount: amount, withdrawalId: withdrawalId)\n }\n function(:markWithdrawalComplete, { to: :address, withdrawalId: :bytes32 }, :public) {\n onlyFactory!\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}\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(:ERC20BridgeFactory, is: [:Ownable, :Pausable, :Upgradeable], upgradeable: true) {\n event(:FactoryBridgedIn, { to: :address, amount: :uint256, smartContract: :address, dumbContract: :address })\n event(:FactoryInitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32, smartContract: :address, dumbContract: :address })\n event(:FactoryWithdrawalComplete, { to: :address, amount: :uint256, withdrawalId: :bytes32, smartContract: :address, dumbContract: :address })\n event(:BridgeCreated, { newBridge: :address, tokenSmartContract: :address })\n address(:public, :trustedSmartContract)\n mapping(({ address: :address }), :public, :bridgeDumbContractToTokenSmartContract)\n mapping(({ address: :address }), :public, :tokenSmartContractToBridgeDumbContract)\n constructor(trustedSmartContract: :address) {\n require(trustedSmartContract != address(0), \"Invalid smart contract\")\n self.Upgradeable.constructor(upgradeAdmin: msg.sender)\n self.Ownable.constructor(owner: msg.sender)\n s.trustedSmartContract=trustedSmartContract\n }\n function(:onlyTrustedSmartContract!, :internal) {\n require(msg.sender == s.trustedSmartContract, \"Only the trusted smart contract can call this function\")\n }\n function(:bridgeIn, { tokenSmartContract: :address, decimals: :uint8, symbol: :string, name: :string, to: :address, amount: :uint256 }, :public) {\n onlyTrustedSmartContract!\n bridge = findOrCreateBridge(tokenSmartContract: tokenSmartContract, decimals: decimals, symbol: symbol, name: name)\n ERC20Bridge(bridge).bridgeIn(to: to, amount: amount)\n emit(:FactoryBridgedIn, to: to, amount: amount, dumbContract: bridge, smartContract: tokenSmartContract)\n }\n function(:bridgeIntoExistingBridge, { tokenSmartContract: :address, to: :address, amount: :uint256 }, :public) {\n onlyTrustedSmartContract!\n bridge = s.tokenSmartContractToBridgeDumbContract[tokenSmartContract]\n require(bridge != address(0), \"Bridge not found\")\n ERC20Bridge(bridge).bridgeIn(to: to, amount: amount)\n emit(:FactoryBridgedIn, to: to, amount: amount, dumbContract: bridge, smartContract: tokenSmartContract)\n }\n function(:findOrCreateBridge, { tokenSmartContract: :address, decimals: :uint8, symbol: :string, name: :string }, :internal, returns: :address) {\n existingBridge = s.tokenSmartContractToBridgeDumbContract[tokenSmartContract]\n if existingBridge != address(0)\n return existingBridge\n end\n salt = keccak256(abi.encodePacked(tokenSmartContract))\n bridge = new(ERC20Bridge(tokenSmartContract, s.trustedSmartContract, \"Facet #{name}\", \"f#{symbol.upcase}\", decimals, { salt: salt }))\n require(s.bridgeDumbContractToTokenSmartContract[bridge] == address(0), \"Bridge already exists\")\n s.tokenSmartContractToBridgeDumbContract[tokenSmartContract] = bridge\n s.bridgeDumbContractToTokenSmartContract[bridge] = tokenSmartContract\n emit(:BridgeCreated, newBridge: bridge, tokenSmartContract: tokenSmartContract)\n return bridge\n }\n function(:bridgeOut, { bridgeDumbContract: :address, amount: :uint256 }, :public) {\n whenNotPaused!\n smartContract = s.bridgeDumbContractToTokenSmartContract[bridgeDumbContract]\n require(smartContract != address(0), \"Bridge not found\")\n ERC20Bridge(bridgeDumbContract).bridgeOut(from: msg.sender, amount: amount)\n emit(:FactoryInitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: tx.current_transaction_hash, dumbContract: bridgeDumbContract, smartContract: smartContract)\n }\n function(:markWithdrawalComplete, { to: :address, withdrawalId: :bytes32, tokenSmartContract: :address }, :public) {\n onlyTrustedSmartContract!\n dumbContract = s.tokenSmartContractToBridgeDumbContract[tokenSmartContract]\n amount = ERC20Bridge(dumbContract).withdrawalIdAmount(withdrawalId)\n ERC20Bridge(dumbContract).markWithdrawalComplete(to: to, withdrawalId: withdrawalId)\n emit(:FactoryWithdrawalComplete, to: to, amount: amount, withdrawalId: withdrawalId, dumbContract: dumbContract, smartContract: tokenSmartContract)\n }\n function(:predictBridgeAddress, { tokenSmartContract: :address }, :public, :view, returns: :address) {\n existing = s.tokenSmartContractToBridgeDumbContract[tokenSmartContract]\n if existing != address(0)\n return existing\n end\n return create2_address(salt: keccak256(abi.encodePacked(tokenSmartContract)), deployer: address(this), contract_type: \"ERC20Bridge\")\n }\n function(:pause, :public) {\n onlyOwner!\n _pause\n }\n function(:unpause, :public) {\n onlyOwner!\n _unpause\n }\n}\n"}}