memoscan
← all memos

Memo 0x887d7675…b0a311 on Ethereum

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\"}}"}}}