diff --git a/.soliumrc.json b/.soliumrc.json index 450acbc769..712f0e541b 100644 --- a/.soliumrc.json +++ b/.soliumrc.json @@ -12,6 +12,7 @@ "error-reason": "error", "max-len": "error", "no-trailing-whitespace": "error", - "blank-lines": "error" + "blank-lines": "error", + "custom-errors": "off" } } diff --git a/contracts/bridging/ColonyShell.sol b/contracts/bridging/ColonyShell.sol new file mode 100644 index 0000000000..02a2e5f49f --- /dev/null +++ b/contracts/bridging/ColonyShell.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + This file is part of The Colony Network. + + The Colony Network is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + The Colony Network is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with The Colony Network. If not, see . +*/ + +pragma solidity 0.8.25; +pragma experimental ABIEncoderV2; + +import { BasicMetaTransaction } from "./../common/BasicMetaTransaction.sol"; +import { CallWithGuards } from "../common/CallWithGuards.sol"; +import { ERC20Extended } from "./../common/ERC20Extended.sol"; +import { Multicall } from "./../common/Multicall.sol"; +import { IColonyNetwork } from "./../colonyNetwork/IColonyNetwork.sol"; + +contract ColonyShell is BasicMetaTransaction, Multicall, CallWithGuards { + // Address of the Resolver contract used by EtherRouter for lookups and routing + address resolver; // Storage slot 2 (from DSAuth there is authority and owner at storage slots 0 and 1 respectively) + + mapping(address => uint256) metatransactionNonces; + + function getMetatransactionNonce(address _user) public view override returns (uint256 _nonce) { + return metatransactionNonces[_user]; + } + + function incrementMetatransactionNonce(address _user) internal override { + metatransactionNonces[_user] += 1; + } + + // Public functions + + function claimColonyFunds(address _token) public { + uint256 tokenBalance = (_token == address(0x0)) + ? address(this).balance + : ERC20Extended(_token).balanceOf(address(this)); + + IColonyNetwork(owner).sendClaimColonyFunds(_token, tokenBalance); + + emit ColonyFundsClaimed(_token, tokenBalance); + } + + function transfer(address _token, address _user, uint256 _amount) public auth { + ERC20Extended(_token).transfer(_user, _amount); + + emit PaymentMade(_token, _user, _amount); + } +} diff --git a/contracts/colonyNetwork/ColonyNetworkShells.sol b/contracts/colonyNetwork/ColonyNetworkShells.sol new file mode 100644 index 0000000000..d7b46ade57 --- /dev/null +++ b/contracts/colonyNetwork/ColonyNetworkShells.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + This file is part of The Colony Network. + + The Colony Network is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + The Colony Network is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with The Colony Network. If not, see . +*/ + +pragma solidity 0.8.25; +pragma experimental ABIEncoderV2; + +import { IColony } from "./../colony/IColony.sol"; +import { ICreateX } from "./../../lib/createx/src/ICreateX.sol"; +import { Multicall } from "./../common/Multicall.sol"; +import { CallWithGuards } from "./../common/CallWithGuards.sol"; +import { ColonyNetworkStorage } from "./ColonyNetworkStorage.sol"; +import { ColonyShell } from "./../briding/ColonyShell.sol"; + +contract ColonyNetworkShells is ColonyNetworkStorage, Multicall, CallWithGuards { + // To shells + + function deployColonyShell(bytes32 _salt) public onlyColonyBridge { + ICreateX(CREATEX_ADDRESS).deployCreate3AndInit( + _salt, + type(EtherRouterCreate3).creationCode, + abi.encodeWithSignature("setOwner(address)", (address(this))), + ICreateX.Values(0, 0) + ); + } + + function sendDeployColonyShell(bytes32 _salt) public onlyColony { + bytes memory payload = abi.encodeWithSignature( + "deployColonyShell(bytes32)", + _salt + ); + + require(callThroughBridgeWithGuards(payload), "colony-network-shell-deploy-failed"); + } + + function colonyShellTransfer(address _colony, address _token, address _user, uint256 _amount) public onlyColonyBridge { + ColonyShell(_colony).transfer(_token, _user, _amount); + } + + function sendColonyShellTransfer(address _token, address _user, uint256 _amount) public onlyColony { + bytes memory payload = abi.encodeWithSignature( + "colonyShellTransfer(address,address,address,uint256)", + msgSender(), + _token, + _user, + _amount + ); + + require(callThroughBridgeWithGuards(payload), "colony-network-shell-transfer-failed"); + } + + // From shells + + function claimColonyShellFunds(address _colony, address _token, uint256 _balance) public onlyColonyBridge { + IColony(_colony).claimColonyShellFunds(_token, _balance); + } + + function sendClaimColonyShellFunds(address _token, uint256 _balance) public onlyColony { + bytes memory payload = abi.encodeWithSignature( + "claimColonyShellFunds(address,address,uint256)", + msgSender(), + _token, + _balance + ); + + require(callThroughBridgeWithGuards(payload), "colony-network-shell-claim-failed"); + } +}