diff --git a/add-collateral.json b/add-collateral.json index 7518f851..61605ac8 100644 --- a/add-collateral.json +++ b/add-collateral.json @@ -1 +1 @@ -{"51":{"tokenAddress":"0x0000000000000000000000000000000000000000","testOracle":"0x0000000000000000000000000000000000000000","fathomProxyFactory":"0x0000000000000000000000000000000000000000","fathomProxyAdmin":"0x0000000000000000000000000000000000000000"},"31337":{"tokenAddress":"0x828e4F72BC7B912f6Fde900071212aAA075BBd22","testOracle":"0x0dC763b6a547deb5ED263cdf26B5e4D456989582","fathomProxyFactory":"0x28c6408131836B0f1Adbae443b65B76487723C4b","fathomProxyAdmin":"0xc38d2D6bc857129aAAd365eDae5f7f286f4Ce994"},"token":"GLD"} \ No newline at end of file +{"51":{"tokenAddress":"0x0000000000000000000000000000000000000000","testOracle":"0x0000000000000000000000000000000000000000","fathomProxyFactory":"0x0000000000000000000000000000000000000000","fathomProxyAdmin":"0x0000000000000000000000000000000000000000"},"31337":{"tokenAddress":"0x22879cD092f74aBA6d198B053f25b7e26BBbd5Da","testOracle":"0x828e4F72BC7B912f6Fde900071212aAA075BBd22","fathomProxyFactory":"0x13cdf6cA2C1c216198FB51A4c515FDa6F11B9dE0","fathomProxyAdmin":"0x28c6408131836B0f1Adbae443b65B76487723C4b"},"token":"GLD"} \ No newline at end of file diff --git a/contracts/main/bridge/AsterizmClientUpgradeableTransparency.sol b/contracts/main/bridge/AsterizmClientUpgradeableTransparency.sol deleted file mode 100644 index 6e326696..00000000 --- a/contracts/main/bridge/AsterizmClientUpgradeableTransparency.sol +++ /dev/null @@ -1,511 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import "asterizmprotocol/contracts/evm/interfaces/IInitializerSender.sol"; -import "asterizmprotocol/contracts/evm/interfaces/IClientReceiverContract.sol"; -import "asterizmprotocol/contracts/evm/base/AsterizmEnv.sol"; -import "asterizmprotocol/contracts/evm/base/AsterizmWithdrawalUpgradeable.sol"; -import "asterizmprotocol/contracts/evm/libs/AddressLib.sol"; -import "asterizmprotocol/contracts/evm/libs/UintLib.sol"; -import "asterizmprotocol/contracts/evm/libs/AsterizmHashLib.sol"; - -abstract contract AsterizmClientUpgradeableTransparency is IClientReceiverContract, AsterizmEnv, AsterizmWithdrawalUpgradeable { - - using AddressLib for address; - using UintLib for uint; - using AsterizmHashLib for bytes; - - /// Set initializer event - /// @param _initializerAddress address Initializer address - event SetInitializerEvent(address _initializerAddress); - - /// Set external relay event - /// @param _externalRelayAddress address External relay address - event SetExternalRelayEvent(address _externalRelayAddress); - - /// Set fee token event - /// @param _feeTokenAddress address Fee token address - event SetFeeTokenEvent(address _feeTokenAddress); - - /// Set local chain id event - /// @param _localChainId uint64 - event SetLocalChainIdEvent(uint64 _localChainId); - - /// Initiate transfer event (for client server logic) - /// @param _dstChainId uint64 Destination chein ID - /// @param _dstAddress uint Destination address - /// @param _txId uint Transaction ID - /// @param _transferHash bytes32 Transfer hash - /// @param _payload bytes Payload - event InitiateTransferEvent(uint64 _dstChainId, uint _dstAddress, uint _txId, bytes32 _transferHash, bytes _payload); - - /// Payload receive event (for client server logic) - /// @param _srcChainId uint64 Source chain ID - /// @param _srcAddress uint Source address - /// @param _txId uint Transfer ID - /// @param _transferHash bytes32 Transaction hash - event PayloadReceivedEvent(uint64 _srcChainId, uint _srcAddress, uint _txId, bytes32 _transferHash); - - /// Add sender event - /// @param _sender address Sender address - event AddSenderEvent(address _sender); - - /// Remove sender event - /// @param _sender address Sender address - event RemoveSenderEvent(address _sender); - - /// Add trusted address event - /// @param _chainId uint64 Chain ID - /// @param _address uint Trusted address - event AddTrustedAddressEvent(uint64 _chainId, uint _address); - - /// Remove trusted address event - /// @param _chainId uint64 Chain ID - /// @param _address uint Trusted address - event RemoveTrustedAddressEvent(uint64 _chainId, uint _address); - - /// Set notify transfer sending result event - /// @param _flag bool Notify transfer sending result flag - event SetNotifyTransferSendingResultEvent(bool _flag); - - /// Set disable hash validation flag event - /// @param _flag bool Use force order flag - event SetDisableHashValidationEvent(bool _flag); - - /// Resend Asterizm transfer event - /// @param _transferHash bytes32 Transfer hash - /// @param _feeAmount uint Additional fee amount - event ResendAsterizmTransferEvent(bytes32 _transferHash, uint _feeAmount); - - /// Transfer sending result notification event - /// @param _transferHash bytes32 Transfer hash - /// @param _statusCode uint8 Status code - event TransferSendingResultNotification(bytes32 indexed _transferHash, uint8 _statusCode); - - struct AsterizmTransfer { - bool successReceive; - bool successExecute; - } - - struct AsterizmChain { - bool exists; - uint trustedAddress; - uint8 chainType; - } - struct Sender { - bool exists; - } - - IInitializerSender private initializerLib; - address private externalRelay; - mapping(uint64 => AsterizmChain) private trustedAddresses; - mapping(bytes32 => AsterizmTransfer) private inboundTransfers; - mapping(bytes32 => AsterizmTransfer) private outboundTransfers; - mapping(address => Sender) private senders; - bool private notifyTransferSendingResult; - bool private disableHashValidation; - uint private txId; - uint64 private localChainId; - IERC20 private feeToken; - - /// Initializing function for upgradeable contracts (constructor) - /// @param _initializerLib IInitializerSender Initializer library address - /// @param _notifyTransferSendingResult bool Transfer sending result notification flag - /// @param _disableHashValidation bool Disable hash validation flag - function _asterizm_initialize(IInitializerSender _initializerLib, bool _notifyTransferSendingResult, bool _disableHashValidation) internal { - __Ownable_init(); - __ReentrancyGuard_init(); - - _setInitializer(_initializerLib); - _setLocalChainId(initializerLib.getLocalChainId()); - _setNotifyTransferSendingResult(_notifyTransferSendingResult); - _setDisableHashValidation(_disableHashValidation); - addSender(owner()); - addTrustedAddress(localChainId, address(this).toUint()); - } - - /// Only initializer modifier - modifier onlyInitializer { - require(msg.sender == address(initializerLib), "AsterizmClient: only initializer"); - _; - } - - /// Only owner or initializer modifier - modifier onlyOwnerOrInitializer { - require(msg.sender == owner() || msg.sender == address(initializerLib), "AsterizmClient: only owner or initializer"); - _; - } - - /// Only sender modifier - modifier onlySender { - require(senders[msg.sender].exists, "AsterizmClient: only sender"); - _; - } - - /// Only sender or owner modifier - modifier onlySenderOrOwner { - require(msg.sender == owner() || senders[msg.sender].exists, "AsterizmClient: only sender or owner"); - _; - } - - /// Only trusted address modifier - /// You must add trusted addresses in production networks! - modifier onlyTrustedAddress(uint64 _chainId, uint _address) { - require(trustedAddresses[_chainId].trustedAddress == _address, "AsterizmClient: wrong source address"); - _; - } - - /// Only trusted trarnsfer modifier - /// Validate transfer hash on initializer - /// Use this modifier for validate transfer by hash - /// @param _transferHash bytes32 Transfer hash - modifier onlyTrustedTransfer(bytes32 _transferHash) { - require(initializerLib.validIncomeTransferHash(_transferHash), "AsterizmClient: transfer hash is invalid"); - _; - } - - /// Only received transfer modifier - /// @param _transferHash bytes32 Transfer hash - modifier onlyReceivedTransfer(bytes32 _transferHash) { - require(inboundTransfers[_transferHash].successReceive, "AsterizmClient: transfer not received"); - _; - } - - /// Only non-executed transfer modifier - /// @param _transferHash bytes32 Transfer hash - modifier onlyNonExecuted(bytes32 _transferHash) { - require(!inboundTransfers[_transferHash].successExecute, "AsterizmClient: transfer executed already"); - _; - } - - /// Only exists outbound transfer modifier - /// @param _transferHash bytes32 Transfer hash - modifier onlyExistsOutboundTransfer(bytes32 _transferHash) { - require(outboundTransfers[_transferHash].successReceive, "AsterizmClient: outbound transfer not exists"); - _; - } - - /// Only not executed outbound transfer modifier - /// @param _transferHash bytes32 Transfer hash - modifier onlyNotExecutedOutboundTransfer(bytes32 _transferHash) { - require(!outboundTransfers[_transferHash].successExecute, "AsterizmClient: outbound transfer executed already"); - _; - } - - /// Only executed outbound transfer modifier - /// @param _transferHash bytes32 Transfer hash - modifier onlyExecutedOutboundTransfer(bytes32 _transferHash) { - require(outboundTransfers[_transferHash].successExecute, "AsterizmClient: outbound transfer not executed"); - _; - } - - /// Only nvalid transfer hash modifier - /// @param _dto ClAsterizmReceiveRequestDto Transfer data - modifier onlyValidTransferHash(ClAsterizmReceiveRequestDto memory _dto) { - if (!disableHashValidation) { - require( - _validTransferHash(_dto.srcChainId, _dto.srcAddress, _dto.dstChainId, _dto.dstAddress, _dto.txId, _dto.payload, _dto.transferHash), - "AsterizmClient: transfer hash is invalid" - ); - } - _; - } - - /** Internal logic */ - - /// Set initizlizer library - /// _initializerLib IInitializerSender Initializer library - function _setInitializer(IInitializerSender _initializerLib) private { - initializerLib = _initializerLib; - emit SetInitializerEvent(address(_initializerLib)); - } - - /// Set local chain id library - /// _localChainId uint64 - function _setLocalChainId(uint64 _localChainId) private { - localChainId = _localChainId; - emit SetLocalChainIdEvent(_localChainId); - } - - /// Set notify transfer sending result - /// _flag bool Transfer sending result notification flag - function _setNotifyTransferSendingResult(bool _flag) private { - notifyTransferSendingResult = _flag; - emit SetNotifyTransferSendingResultEvent(_flag); - } - - /// Set disable hash validation flag - /// _flag bool Disable hash validation flag - function _setDisableHashValidation(bool _flag) private { - disableHashValidation = _flag; - emit SetDisableHashValidationEvent(_flag); - } - - /// Return chain type by id - /// @param _chainId uint64 Chain id - /// @return uint8 Chain type - function _getChainType(uint64 _chainId) internal view returns(uint8) { - return initializerLib.getChainType(_chainId); - } - - /// Set external relay address (one-time initiation) - /// _externalRelay address External relay address - function setExternalRelay(address _externalRelay) public onlyOwner { - require(externalRelay == address(0), "AsterizmClient: relay changing not available"); - externalRelay = _externalRelay; - emit SetExternalRelayEvent(_externalRelay); - } - - /// Return external relay - /// @return address External relay address - function getExternalRelay() external view returns(address) { - return externalRelay; - } - - /// Set external relay address (one-time initiation) - /// _feeToken IERC20 External relay address - function setFeeToken(IERC20 _feeToken) public onlyOwner { - feeToken = _feeToken; - emit SetFeeTokenEvent(address(_feeToken)); - } - - /// Return fee token - /// @return address Fee token address - function getFeeToken() external view returns(address) { - return address(feeToken); - } - - /// Add sender - /// @param _sender address Sender address - function addSender(address _sender) public onlyOwner { - senders[_sender].exists = true; - emit AddSenderEvent(_sender); - } - - /// Remove sender - /// @param _sender address Sender address - function removeSender(address _sender) public onlyOwner { - require(senders[_sender].exists, "AsterizmClient: sender not exists"); - delete senders[_sender]; - emit RemoveSenderEvent(_sender); - } - - /// Add trusted address - /// @param _chainId uint64 Chain ID - /// @param _trustedAddress address Trusted address - function addTrustedAddress(uint64 _chainId, uint _trustedAddress) public onlyOwner { - trustedAddresses[_chainId].exists = true; - trustedAddresses[_chainId].trustedAddress = _trustedAddress; - trustedAddresses[_chainId].chainType = initializerLib.getChainType(_chainId); - - emit AddTrustedAddressEvent(_chainId, _trustedAddress); - } - - /// Add trusted addresses - /// @param _chainIds uint64[] Chain IDs - /// @param _trustedAddresses uint[] Trusted addresses - function addTrustedAddresses(uint64[] calldata _chainIds, uint[] calldata _trustedAddresses) external onlyOwner { - for (uint i = 0; i < _chainIds.length; i++) { - addTrustedAddress(_chainIds[i], _trustedAddresses[i]); - } - } - - /// Remove trusted address - /// @param _chainId uint64 Chain ID - function removeTrustedAddress(uint64 _chainId) external onlyOwner { - require(trustedAddresses[_chainId].exists, "AsterizmClient: trusted address not found"); - uint removingAddress = trustedAddresses[_chainId].trustedAddress; - delete trustedAddresses[_chainId]; - - emit RemoveTrustedAddressEvent(_chainId, removingAddress); - } - - /// Build transfer hash - /// @param _srcChainId uint64 Chain ID - /// @param _srcAddress uint Address - /// @param _dstChainId uint64 Chain ID - /// @param _dstAddress uint Address - /// @param _txId uint Transaction ID - /// @param _payload bytes Payload - function _buildTransferHash(uint64 _srcChainId, uint _srcAddress, uint64 _dstChainId, uint _dstAddress, uint _txId, bytes memory _payload) internal view returns(bytes32) { - bytes memory encodeData = abi.encodePacked(_srcChainId, _srcAddress, _dstChainId, _dstAddress, _txId, _buildPackedPayload(_payload)); - - return _getChainType(_srcChainId) == _getChainType(_dstChainId) ? encodeData.buildSimpleHash() : encodeData.buildCrosschainHash(); - } - - /// Check is transfer hash valid - /// @param _srcChainId uint64 Chain ID - /// @param _srcAddress uint Address - /// @param _dstChainId uint64 Chain ID - /// @param _dstAddress uint Address - /// @param _txId uint Transaction ID - /// @param _payload bytes Packed payload - /// @param _transferHash bytes32 Transfer hash - function _validTransferHash(uint64 _srcChainId, uint _srcAddress, uint64 _dstChainId, uint _dstAddress, uint _txId, bytes memory _payload, bytes32 _transferHash) internal view returns(bool) { - return _buildTransferHash(_srcChainId, _srcAddress, _dstChainId, _dstAddress, _txId, _payload) == _transferHash; - } - - /// Return txId - /// @return uint - function _getTxId() internal view returns(uint) { - return txId; - } - - /// Return local chain id - /// @return uint64 - function _getLocalChainId() internal view returns(uint64) { - return localChainId; - } - - /// Return initializer address - /// @return address - function getInitializerAddress() external view returns(address) { - return address(initializerLib); - } - - /// Return trusted src addresses - /// @param _chainId uint64 Chain id - /// @return AsterizmChain - function getTrustedAddresses(uint64 _chainId) external view returns(AsterizmChain memory) { - return trustedAddresses[_chainId]; - } - - /// Return disable hash validation flag - /// @return bool - function getDisableHashValidation() external view returns(bool) { - return disableHashValidation; - } - - /// Return notify transfer sending result flag - /// @return bool - function getNotifyTransferSendingResult() external view returns(bool) { - return notifyTransferSendingResult; - } - - /** Sending logic */ - - /// Initiate transfer event - /// Generate event for client server - /// @param _dstChainId uint64 Destination chain ID - /// @param _payload bytes Payload - function _initAsterizmTransferEvent(uint64 _dstChainId, bytes memory _payload) internal { - require(trustedAddresses[_dstChainId].exists, "AsterizmClient: trusted address not found"); - uint id = txId++; - bytes32 transferHash = _buildTransferHash(_getLocalChainId(), address(this).toUint(), _dstChainId, trustedAddresses[_dstChainId].trustedAddress, id, _payload); - outboundTransfers[transferHash].successReceive = true; - emit InitiateTransferEvent(_dstChainId, trustedAddresses[_dstChainId].trustedAddress, id, transferHash, _payload); - } - - /// External initiation transfer - /// This function needs for external initiating non-encoded payload transfer - /// @param _dstChainId uint64 Destination chain ID - /// @param _transferHash bytes32 Transfer hash - /// @param _txId uint Transaction ID - function initAsterizmTransfer(uint64 _dstChainId, uint _txId, bytes32 _transferHash) external payable onlySender nonReentrant { - require(trustedAddresses[_dstChainId].exists, "AsterizmClient: trusted address not found"); - ClInitTransferRequestDto memory dto = _buildClInitTransferRequestDto(_dstChainId, trustedAddresses[_dstChainId].trustedAddress, _txId, _transferHash, msg.value); - _initAsterizmTransferPrivate(dto); - } - - /// Private initiation transfer - /// This function needs for internal initiating non-encoded payload transfer - /// @param _dto ClInitTransferRequestDto Init transfer DTO - function _initAsterizmTransferPrivate(ClInitTransferRequestDto memory _dto) private - onlyExistsOutboundTransfer(_dto.transferHash) - onlyNotExecutedOutboundTransfer(_dto.transferHash) - { - require(address(this).balance >= _dto.feeAmount, "AsterizmClient: contract balance is not enough"); - require(_dto.txId <= _getTxId(), "AsterizmClient: wrong txId param"); - - IzInitTransferRequestDto memory initDto = _buildIzInitTransferRequestDto( - _dto.dstChainId, _dto.dstAddress, _dto.txId, _dto.transferHash, - externalRelay, notifyTransferSendingResult, address(feeToken) - ); - - if (address(feeToken) != address(0)) { - uint feeAmountInToken = initializerLib.getFeeAmountInTokens(externalRelay, initDto); - if (feeAmountInToken > 0) { - require(feeToken.balanceOf(address(this)) >= feeAmountInToken, "AsterizmClient: fee token balance is not enough"); - feeToken.approve(address(initializerLib), feeAmountInToken); - } - } - - initializerLib.initTransfer{value: _dto.feeAmount} (initDto); - outboundTransfers[_dto.transferHash].successExecute = true; - } - - /// Resend failed by fee amount transfer - /// @param _transferHash bytes32 Transfer hash - function resendAsterizmTransfer(bytes32 _transferHash) external payable - onlyOwner - onlyExistsOutboundTransfer(_transferHash) - onlyExecutedOutboundTransfer(_transferHash) - { - initializerLib.resendTransfer{value: msg.value}(_transferHash, externalRelay); - emit ResendAsterizmTransferEvent(_transferHash, msg.value); - } - - /// Transfer sending result notification - /// @param _transferHash bytes32 Transfer hash - /// @param _statusCode uint8 Status code - function transferSendingResultNotification(bytes32 _transferHash, uint8 _statusCode) external onlyInitializer onlyExecutedOutboundTransfer(_transferHash) { - if (notifyTransferSendingResult) { - emit TransferSendingResultNotification(_transferHash, _statusCode); - } - } - - /** Receiving logic */ - - /// Receive payload from initializer - /// @param _dto IzAsterizmReceiveRequestDto Method DTO - function asterizmIzReceive(IzAsterizmReceiveRequestDto calldata _dto) external onlyInitializer { - _asterizmReceiveExternal(_dto); - } - - /// Receive external payload - /// @param _dto IzAsterizmReceiveRequestDto Method DTO - function _asterizmReceiveExternal(IzAsterizmReceiveRequestDto calldata _dto) private - onlyOwnerOrInitializer - onlyTrustedAddress(_dto.srcChainId, _dto.srcAddress) - onlyNonExecuted(_dto.transferHash) - { - inboundTransfers[_dto.transferHash].successReceive = true; - emit PayloadReceivedEvent(_dto.srcChainId, _dto.srcAddress, _dto.txId, _dto.transferHash); - } - - /// Receive payload from client server - /// @param _srcChainId uint64 Source chain ID - /// @param _srcAddress uint Source address - /// @param _txId uint Transaction ID - /// @param _transferHash bytes32 Transfer hash - /// @param _payload bytes Payload - function asterizmClReceive(uint64 _srcChainId, uint _srcAddress, uint _txId, bytes32 _transferHash, bytes calldata _payload) external onlySender nonReentrant { - ClAsterizmReceiveRequestDto memory dto = _buildClAsterizmReceiveRequestDto(_srcChainId, _srcAddress, localChainId, address(this).toUint(), _txId, _transferHash, _payload); - _asterizmReceiveInternal(dto); - } - - /// Receive non-encoded payload for internal usage - /// @param _dto ClAsterizmReceiveRequestDto Method DTO - function _asterizmReceiveInternal(ClAsterizmReceiveRequestDto memory _dto) private - onlyOwnerOrInitializer - onlyReceivedTransfer(_dto.transferHash) - onlyTrustedAddress(_dto.srcChainId, _dto.srcAddress) - onlyTrustedTransfer(_dto.transferHash) - onlyNonExecuted(_dto.transferHash) - onlyValidTransferHash(_dto) - { - _asterizmReceive(_dto); - inboundTransfers[_dto.transferHash].successExecute = true; - } - - /// Receive payload - /// You must realize this function if you want to transfer payload - /// If disableHashValidation = true you must validate transferHash with _validTransferHash() method for more security! - /// @param _dto ClAsterizmReceiveRequestDto Method DTO - function _asterizmReceive(ClAsterizmReceiveRequestDto memory _dto) internal virtual {} - - /// Build packed payload (abi.encodePacked() result) - /// @param _payload bytes Default payload (abi.encode() result) - /// @return bytes Packed payload (abi.encodePacked() result) - function _buildPackedPayload(bytes memory _payload) internal view virtual returns(bytes memory) {} -} diff --git a/contracts/main/bridge/FathomBridge.sol b/contracts/main/bridge/FathomBridge.sol deleted file mode 100644 index dfc77701..00000000 --- a/contracts/main/bridge/FathomBridge.sol +++ /dev/null @@ -1,159 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later -pragma solidity 0.8.17; - -import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; -import "./AsterizmClientUpgradeableTransparency.sol"; -import "../interfaces/IAccessControlConfig.sol"; -import "../interfaces/IStablecoin.sol"; -import "../interfaces/ICagable.sol"; -import "../interfaces/IFathomBridge.sol"; -import "../utils/SafeToken.sol"; - -contract FathomBridge is AsterizmClientUpgradeableTransparency, PausableUpgradeable, IFathomBridge, ICagable { - using SafeToken for address; - address public stablecoin; - IAccessControlConfig public accessControlConfig; - uint256 public fixedBridgeFee; // fixed fee [wad] - uint256 public live; // Active Flag - bool public isDecentralizedMode; - mapping(address => bool) public whitelisted; - mapping(uint64 => uint256) public bridgedInAmount; // [wad] - mapping(uint64 => uint256) public bridgedOutAmount; // [wad] - uint256 public override totalBridgedInAmount; // [wad] - uint256 public override totalBridgedOutAmount; // [wad] - - modifier onlyOwnerOrGov() { - require( - accessControlConfig.hasRole(accessControlConfig.OWNER_ROLE(), msg.sender) || - accessControlConfig.hasRole(accessControlConfig.GOV_ROLE(), msg.sender), - "!(ownerRole or govRole)" - ); - _; - } - - modifier onlyOwnerOrShowStopper() { - require( - accessControlConfig.hasRole(accessControlConfig.OWNER_ROLE(), msg.sender) || - accessControlConfig.hasRole(accessControlConfig.SHOW_STOPPER_ROLE(), msg.sender), - "!(ownerRole or showStopperRole)" - ); - _; - } - - modifier onlyWhitelisted() { - if (!whitelisted[msg.sender] && !isDecentralizedMode) { - revert("FathomBridge/not-whitelisted"); - } - _; - } - - constructor() { - _disableInitializers(); - } - - // --- Init --- - - function initialize(IInitializerSender _initializerLib, address _stablecoin, address _accessControlConfig) external initializer { - _zeroAddressCheck(address(_initializerLib)); - _zeroAddressCheck(_stablecoin); - _zeroAddressCheck(_accessControlConfig); - stablecoin = _stablecoin; - accessControlConfig = IAccessControlConfig(_accessControlConfig); - live = 1; - whitelisted[msg.sender] = true; - _asterizm_initialize(_initializerLib, true, false); - } - - // --- Whitelisting --- - - function addToWhitelist(address _usr) external onlyOwnerOrGov { - _zeroAddressCheck(_usr); - whitelisted[_usr] = true; - emit LogAddToWhitelist(_usr); - } - - function removeFromWhitelist(address _usr) external onlyOwnerOrGov { - _zeroAddressCheck(_usr); - whitelisted[_usr] = false; - emit LogRemoveFromWhitelist(_usr); - } - - // --- Administration --- - - function setDecentralizedMode(bool _isOn) external onlyOwnerOrGov { - isDecentralizedMode = _isOn; - emit LogSetDecentralizedMode(_isOn); - } - - function setFee(uint256 _newFee) external onlyOwnerOrGov { - fixedBridgeFee = _newFee; - emit LogSetFee(_newFee); - } - - function withdrawFees(address _to) external onlyOwnerOrGov { - _zeroAddressCheck(_to); - stablecoin.safeTransfer(_to, stablecoin.balanceOf(address(this))); - emit LogWithdrawFees(msg.sender, _to, stablecoin.balanceOf(address(this))); - } - - /// Cross-chain transfer - /// @notice This function is used to transfer FXD from the source chain to the destination chain. - /// It works only when the off chain client module is up and running to listen to this function's event. - /// works only when the sender is whitelisted or in decentralized mode - /// @param _dstChainId uint64 Destination chain ID - /// @param _to address To address - /// @param _amount uint Amount - function crossChainTransfer(uint64 _dstChainId, address _to, uint _amount) external onlyWhitelisted nonReentrant{ - require(live == 1, "FathomBridge/not-live"); - require(_amount > fixedBridgeFee, "FathomBridge/amount-less-than-fee"); - _zeroAddressCheck(_to); - - stablecoin.safeTransferFrom(msg.sender, address(this), _amount); - uint256 _actualTransferAmount = fixedBridgeFee != 0 ? _amount - fixedBridgeFee : _amount; - IStablecoin(stablecoin).burn(address(this), _actualTransferAmount); - - bridgedOutAmount[_dstChainId] = bridgedOutAmount[_dstChainId] + _actualTransferAmount; - totalBridgedOutAmount = totalBridgedOutAmount + _actualTransferAmount; - - //generate event for off-chain components - _initAsterizmTransferEvent(_dstChainId, abi.encode(msg.sender, _to, _actualTransferAmount)); - emit LogCrossChainTransferOut(_dstChainId, msg.sender, _to, _actualTransferAmount, _getTxId()); - emit LogFeeCollection(msg.sender, fixedBridgeFee, _getTxId()); - } - - /// Cross-chain fn that triggers when receiving payload from another chain - /// Minting logic on the receiver side - function _asterizmReceive(ClAsterizmReceiveRequestDto memory _dto) internal override { - (address _from, address _to, uint _amount) = abi.decode(_dto.payload, (address, address, uint256)); - bridgedInAmount[_dto.srcChainId] = bridgedInAmount[_dto.srcChainId] + _amount; - totalBridgedInAmount = totalBridgedInAmount + _amount; - IStablecoin(stablecoin).mint(_to, _amount); - emit LogCrossChainTransferIn(_dto.srcChainId, _from, _to, _amount); - } - - function _zeroAddressCheck(address _address) internal pure { - require(_address != address(0), "FathomBridge/zero-address"); - } - - /// @dev The `cage` function permanently halts the `collateralTokenAdapter` contract. - /// Please exercise caution when using this function as there is no corresponding `uncage` function. - /// The `cage` function in this contract is unique because it must be called before users can initiate `emergencyWithdraw` in the `collateralTokenAdapter`. - /// It's a must to invoke this function in the `collateralTokenAdapter` during the final phase of an emergency shutdown. - function cage() external override nonReentrant onlyOwnerOrShowStopper { - if (live == 1) { - live = 0; - emit LogCage(); - } - } - - /// @dev access: OWNER_ROLE, GOV_ROLE - function pause() external onlyOwnerOrGov { - _pause(); - } - - /// @dev access: OWNER_ROLE, GOV_ROLE - function unpause() external onlyOwnerOrGov { - _unpause(); - } - -} \ No newline at end of file diff --git a/contracts/main/interfaces/IBookKeeper.sol b/contracts/main/interfaces/IBookKeeper.sol index 0a5cae3a..9f694ea6 100644 --- a/contracts/main/interfaces/IBookKeeper.sol +++ b/contracts/main/interfaces/IBookKeeper.sol @@ -22,7 +22,7 @@ interface IBookKeeper { int256 _debtShare ) external; - function totalStablecoinIssued() external view returns (uint256); + function totalStablecoinIssued() external returns (uint256); function moveStablecoin( address _src, diff --git a/contracts/main/interfaces/IFathomBridge.sol b/contracts/main/interfaces/IFathomBridge.sol deleted file mode 100644 index a89de0ab..00000000 --- a/contracts/main/interfaces/IFathomBridge.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later -pragma solidity 0.8.17; - -/** - * @title FathomBridge - * @notice A contract which acts as an entrypoint for bridging Fathom Stablecoin. - * It has the ability to mint FXD in the source chain and burn FXD in the destination chain. - * _initializerLib contract needs to exist prior to the deployment of this smart contract. - * Please refer to below documentation for the list of deployed AsterizmInitializerLib contract - * https://docs.asterizm.io/technical-reference/mainnet - * This contract, like FathomProxyAdmin&FathomProxyFactory, has its own owner outside of Fathom Protocol's accessControlSystem due to inheritance of AsterizmClientUpgradeableTransparency - * Have the off-chain client module as the OZ owner of this contract to manage bridge related operations - */ - -interface IFathomBridge { - - event LogAddToWhitelist(address indexed _user); - event LogRemoveFromWhitelist(address indexed _user); - event LogSetFee(uint256 _newFee); - event LogWithdrawFees(address indexed _withdrawer, address indexed _to, uint256 _amount); - event LogFeeCollection(address indexed _from, uint256 _amount, uint256 _txId); - event LogSetDecentralizedMode(bool _newValue); - event LogCrossChainTransferOut(uint64 indexed _dstChainId, address indexed _from, address indexed _to, uint256 _amount, uint256 _txId); - event LogCrossChainTransferIn(uint64 indexed _srcChainId, address indexed _from, address indexed _to, uint256 _amount); - - - function crossChainTransfer(uint64 _dstChainId, address _to, uint _amount) external; - - function totalBridgedInAmount() external view returns (uint256); - - function totalBridgedOutAmount() external view returns (uint256); - -} \ No newline at end of file diff --git a/contracts/main/stablecoin-core/ShowStopper.sol b/contracts/main/stablecoin-core/ShowStopper.sol index e62b8257..73a4dbb4 100644 --- a/contracts/main/stablecoin-core/ShowStopper.sol +++ b/contracts/main/stablecoin-core/ShowStopper.sol @@ -9,7 +9,6 @@ import "../interfaces/ILiquidationEngine.sol"; import "../interfaces/IPriceFeed.sol"; import "../interfaces/IPriceOracle.sol"; import "../interfaces/ISystemDebtEngine.sol"; -import "../interfaces/IFathomBridge.sol"; import "../interfaces/ICagable.sol"; import "../utils/CommonMath.sol"; @@ -39,8 +38,6 @@ contract ShowStopper is CommonMath, IShowStopper, PausableUpgradeable { mapping(address => uint256) public stablecoinAccumulator; // [wad] mapping(bytes32 => mapping(address => uint256)) public redeemedStablecoinAmount; // [wad] - IFathomBridge public fathomBridge; - event LogCage(uint256 _cageCoolDown); event LogCageCollateralPool(bytes32 indexed _collateralPoolId); @@ -55,7 +52,6 @@ contract ShowStopper is CommonMath, IShowStopper, PausableUpgradeable { event LogSetLiquidationEngine(address indexed _caller, address _liquidationEngine); event LogSetSystemDebtEngine(address indexed _caller, address _systemDebtEngine); event LogSetPriceOracle(address indexed _caller, address _priceOracle); - event LogSetFathomBridge(address indexed _caller, address _fathomBridge); event LogSetCageCoolDown(address indexed _caller, uint256 _cageCoolDown); modifier onlyOwner() { @@ -103,12 +99,6 @@ contract ShowStopper is CommonMath, IShowStopper, PausableUpgradeable { emit LogSetPriceOracle(msg.sender, _priceOracle); } - function setFathomBridge(address _fathomBridge) external onlyOwner { - require(live == 1, "ShowStopper/not-live"); - fathomBridge = IFathomBridge(_fathomBridge); - emit LogSetFathomBridge(msg.sender, _fathomBridge); - } - /// @notice Initiates the process of emergency shutdown (cage). /// @dev This function can only be called by the contract owner. /// @param _cageCoolDown Length of the cooldown period for the emergency shutdown, in seconds. @@ -183,8 +173,7 @@ contract ShowStopper is CommonMath, IShowStopper, PausableUpgradeable { require(debt == 0, "ShowStopper/debt-not-zero"); require(bookKeeper.stablecoin(address(systemDebtEngine)) == 0, "ShowStopper/surplus-not-zero"); require(block.timestamp >= cagedTimestamp + cageCoolDown, "ShowStopper/cage-cool-down-not-finished"); - _cageBridge(); - debt = _finalizeDebt(); + debt = bookKeeper.totalStablecoinIssued(); emit LogFinalizeDebt(); } @@ -258,25 +247,6 @@ contract ShowStopper is CommonMath, IShowStopper, PausableUpgradeable { emit LogRedeemLockedCollateral(_collateralPoolId, _collateralReceiver, _lockedCollateralAmount); } - function _finalizeDebt() internal view returns (uint256){ - uint256 _totalBridgedInAmount = fathomBridge.totalBridgedInAmount() * RAY; - uint256 _totalBridgedOutAmount = fathomBridge.totalBridgedOutAmount() * RAY; - uint256 _debt = bookKeeper.totalStablecoinIssued(); - if (_totalBridgedInAmount > _totalBridgedOutAmount) { - return _debt + _totalBridgedInAmount - _totalBridgedOutAmount; - } else if (_totalBridgedInAmount < _totalBridgedOutAmount) { - return _debt - (_totalBridgedOutAmount - _totalBridgedInAmount); - } else { - return _debt; - } - } - - function _cageBridge() internal { - if (address(fathomBridge) != address(0)) { - ICagable(address(fathomBridge)).cage(); - } - } - function _safeToInt256(uint256 _number) internal pure returns (int256) { require(int256(_number) >= 0, "ShowStopper/overflow"); return int256(_number); diff --git a/contracts/tests/mocks/MockFathomBridge.sol b/contracts/tests/mocks/MockFathomBridge.sol deleted file mode 100644 index 270ebf02..00000000 --- a/contracts/tests/mocks/MockFathomBridge.sol +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later -pragma solidity 0.8.17; - -import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; -import "../../main/interfaces/ICagable.sol"; -import "../../main/interfaces/IAccessControlConfig.sol"; -import "../../main/interfaces/IStablecoin.sol"; -import "../../main/interfaces/IFathomBridge.sol"; -import "../../main/utils/SafeToken.sol"; - - -contract MockFathomBridge is PausableUpgradeable, IFathomBridge, ICagable { - /// Client asterizm receive request DTO - /// @param srcChainId uint64 Source chain ID - /// @param srcAddress uint Source address - /// @param dstChainId uint64 Destination chain ID - /// @param dstAddress uint Destination address - /// @param txId uint Transaction ID - /// @param transferHash bytes32 Transfer hash - /// @param payload bytes Transfer payload - struct ClAsterizmReceiveRequestDto { - uint64 srcChainId; - uint srcAddress; - uint64 dstChainId; - uint dstAddress; - uint txId; - bytes32 transferHash; - bytes payload; - } - - - using SafeToken for address; - uint256 private txId; - address public stablecoin; - IAccessControlConfig public accessControlConfig; - uint256 public fixedBridgeFee; // fixed fee [wad] - uint256 public live; // Active Flag - bool public isDecentralizedMode; - mapping(address => bool) public whitelisted; - mapping(uint64 => uint256) public bridgedInAmount; // [wad] - mapping(uint64 => uint256) public bridgedOutAmount; // [wad] - uint256 public override totalBridgedInAmount; // [wad] - uint256 public override totalBridgedOutAmount; // [wad] - - modifier onlyOwnerOrGov() { - require( - accessControlConfig.hasRole(accessControlConfig.OWNER_ROLE(), msg.sender) || - accessControlConfig.hasRole(accessControlConfig.GOV_ROLE(), msg.sender), - "!(ownerRole or govRole)" - ); - _; - } - - modifier onlyOwnerOrShowStopper() { - require( - accessControlConfig.hasRole(accessControlConfig.OWNER_ROLE(), msg.sender) || - accessControlConfig.hasRole(accessControlConfig.SHOW_STOPPER_ROLE(), msg.sender), - "!(ownerRole or showStopperRole)" - ); - _; - } - - modifier onlyWhitelisted() { - if (!whitelisted[msg.sender] && !isDecentralizedMode) { - revert("FathomBridge/not-whitelisted"); - } - _; - } - - constructor() { - // Must be commented out for test script - // _disableInitializers(); - } - - function initialize(address _stablecoin, address _accessControlConfig) external initializer { - _zeroAddressCheck(_stablecoin); - _zeroAddressCheck(_accessControlConfig); - stablecoin = _stablecoin; - accessControlConfig = IAccessControlConfig(_accessControlConfig); - live = 1; - whitelisted[msg.sender] = true; - // _asterizm_initialize(_initializerLib, true, false); - } - - function addToWhitelist(address _usr) external onlyOwnerOrGov { - _zeroAddressCheck(_usr); - whitelisted[_usr] = true; - emit LogAddToWhitelist(_usr); - } - - function removeFromWhitelist(address _usr) external onlyOwnerOrGov { - _zeroAddressCheck(_usr); - whitelisted[_usr] = false; - emit LogRemoveFromWhitelist(_usr); - } - - function setDecentralizedMode(bool _isOn) external onlyOwnerOrGov { - isDecentralizedMode = _isOn; - emit LogSetDecentralizedMode(_isOn); - } - - function setFee(uint256 _newFee) external onlyOwnerOrGov { - fixedBridgeFee = _newFee; - emit LogSetFee(_newFee); - } - - function withdrawFees(address _to) external onlyOwnerOrGov { - _zeroAddressCheck(_to); - stablecoin.safeTransfer(_to, stablecoin.balanceOf(address(this))); - emit LogWithdrawFees(msg.sender, _to, stablecoin.balanceOf(address(this))); - } - - /// Cross-chain transfer - /// works only when the sender is whitelisted or in decentralized mode - /// @param _dstChainId uint64 Destination chain ID - /// @param _to address To address - /// @param _amount uint Amount - function crossChainTransfer(uint64 _dstChainId, address _to, uint _amount) external onlyWhitelisted { - require(live == 1, "FathomBridge/not-live"); - require(_amount > fixedBridgeFee, "FathomBridge/amount-less-than-fee"); - _zeroAddressCheck(_to); - - uint256 _actualTransferAmount = fixedBridgeFee != 0 ? _amount - fixedBridgeFee : _amount; - IStablecoin(stablecoin).burn(msg.sender, _actualTransferAmount); - stablecoin.safeTransferFrom(msg.sender, address(this), _amount - _actualTransferAmount); - - bridgedOutAmount[_dstChainId] = bridgedOutAmount[_dstChainId] + _amount; - totalBridgedOutAmount = totalBridgedOutAmount + _amount; - - //generate event for off-chain components - _initAsterizmTransferEvent(_dstChainId, abi.encode(msg.sender, _to, _actualTransferAmount)); - emit LogCrossChainTransferOut(_dstChainId, msg.sender, _to, _actualTransferAmount, _getTxId()); - emit LogFeeCollection(msg.sender, fixedBridgeFee, _getTxId()); - } - - /// Cross-chain fn that triggers when receiving payload from another chain - /// Minting logic on the receiver side - function _asterizmReceive(ClAsterizmReceiveRequestDto memory _dto) internal { - (address _from, address _to, uint _amount) = abi.decode(_dto.payload, (address, address, uint256)); - bridgedInAmount[_dto.srcChainId] = bridgedInAmount[_dto.srcChainId] + _amount; - totalBridgedInAmount = totalBridgedInAmount + _amount; - IStablecoin(stablecoin).mint(_to, _amount); - emit LogCrossChainTransferIn(_dto.srcChainId, _from, _to, _amount); - } - - - function _zeroAddressCheck(address _address) internal pure { - require(_address != address(0), "FathomBridge/zero-address"); - } - - /// @dev The `cage` function permanently halts the `collateralTokenAdapter` contract. - /// Please exercise caution when using this function as there is no corresponding `uncage` function. - /// The `cage` function in this contract is unique because it must be called before users can initiate `emergencyWithdraw` in the `collateralTokenAdapter`. - /// It's a must to invoke this function in the `collateralTokenAdapter` during the final phase of an emergency shutdown. - function cage() external override onlyOwnerOrShowStopper { - if (live == 1) { - live = 0; - emit LogCage(); - } - } - - /// @dev access: OWNER_ROLE, GOV_ROLE - function pause() external onlyOwnerOrGov { - _pause(); - } - - /// @dev access: OWNER_ROLE, GOV_ROLE - function unpause() external onlyOwnerOrGov { - _unpause(); - } - - function _initAsterizmTransferEvent(uint64 /**_dstChainId**/ , bytes memory /** _payload **/) internal { - txId++; - } - - function _getTxId() internal view returns(uint) { - return txId; - } - -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 266fa4e3..05b04288 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,7 @@ "dependencies": { "@defi-wonderland/smock": "^2.4.0", "@openzeppelin/contracts": "4.9.2", - "@openzeppelin/contracts-upgradeable": "4.9.2", - "asterizmprotocol": "^1.0.1" + "@openzeppelin/contracts-upgradeable": "4.9.2" }, "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^2.0.2", @@ -2168,12 +2167,6 @@ "dev": true, "license": "MIT" }, - "node_modules/asterizmprotocol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/asterizmprotocol/-/asterizmprotocol-1.0.1.tgz", - "integrity": "sha512-EslHw4Mk5GD+Cr9EEb4zdX0Oz0jFLP7pOhdn5qoDxi6LHu4WxRqUs/1lkQ1N512CP+mW/pdeNp8A5cqiC6YIfQ==", - "license": "MIT" - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", diff --git a/package.json b/package.json index 6a1c6dc8..1fb82bd3 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,7 @@ "dependencies": { "@defi-wonderland/smock": "^2.4.0", "@openzeppelin/contracts": "4.9.2", - "@openzeppelin/contracts-upgradeable": "4.9.2", - "asterizmprotocol": "^1.0.1" + "@openzeppelin/contracts-upgradeable": "4.9.2" }, "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^2.0.2", diff --git a/scripts/setup/deploy-test-fixture/deployMocks.js b/scripts/setup/deploy-test-fixture/deployMocks.js index 6bc0a3c8..d69b6857 100644 --- a/scripts/setup/deploy-test-fixture/deployMocks.js +++ b/scripts/setup/deploy-test-fixture/deployMocks.js @@ -122,11 +122,6 @@ async function deployMocks(getNamedAccounts, deployments, getChainId) { args: [], log: true, }); - await deploy("MockFathomBridge", { - from: deployer, - args: [], - log: true, - }); await deploy("MockShowStopper", { from: deployer, args: [], diff --git a/scripts/setup/deploy/addRoles.js b/scripts/setup/deploy/addRoles.js index d1fe65a9..1f82e792 100644 --- a/scripts/setup/deploy/addRoles.js +++ b/scripts/setup/deploy/addRoles.js @@ -23,14 +23,6 @@ async function addRoles(deployments, getChainId) { const systemDebtEngine = await getProxy(proxyFactory, "SystemDebtEngine"); const adminControls = await getProxy(proxyFactory, "AdminControls"); - let fathomBridge; - if (chainId !== "31337") { - // Get FathomBridge Proxy only on testnet/mainnet - fathomBridge = await getProxy(proxyFactory, "FathomBridge"); - } else { - fathomBridge = null; - } - await accessControlConfig.grantRole(await accessControlConfig.BOOK_KEEPER_ROLE(), bookKeeper.address); await accessControlConfig.grantRole(await accessControlConfig.POSITION_MANAGER_ROLE(), positionManager.address); @@ -58,11 +50,6 @@ async function addRoles(deployments, getChainId) { await accessControlConfig.grantRole(await accessControlConfig.COLLATERAL_MANAGER_ROLE(), systemDebtEngine.address); - // Grant MINTER_ROLE to FathomBridge only on testnet/mainnet - if (chainId !== "31337") { - await fathomStablecoin.grantRole(await fathomStablecoin.MINTER_ROLE(), fathomBridge.address); - } - await fathomStablecoin.grantRole(await fathomStablecoin.MINTER_ROLE(), stablecoinAdapter.address); await accessControlConfig.grantRole(await accessControlConfig.GOV_ROLE(), adminControls.address); diff --git a/scripts/setup/deploy/deployContracts.js b/scripts/setup/deploy/deployContracts.js index a9657397..2dd212a5 100644 --- a/scripts/setup/deploy/deployContracts.js +++ b/scripts/setup/deploy/deployContracts.js @@ -153,14 +153,6 @@ async function deployContracts(getNamedAccounts, deployments, getChainId) { args: [], log: true, }); - // Deploy FathomBridge only on testnet/mainnet - if (chainId !== "31337") { - await deploy("FathomBridge", { - from: deployer, - args: [], - log: true, - }); - } } module.exports = { diff --git a/scripts/setup/deploy/deployProxies.js b/scripts/setup/deploy/deployProxies.js index e978f522..35b8bd61 100644 --- a/scripts/setup/deploy/deployProxies.js +++ b/scripts/setup/deploy/deployProxies.js @@ -29,7 +29,6 @@ const contracts = [ "CentralizedOraclePriceFeed", "StableSwapModuleWrapper", "SimplePriceFeed", - // "FathomBridge", ]; async function deployProxies(deployments, getChainId) { @@ -48,12 +47,6 @@ async function deployProxies(deployments, getChainId) { return fathomProxyFactoryContract.createProxy(formatBytes32String(contract), instance.address, fathomProxyAdminAddress, "0x"); }) ); - - // Create FathomBridge Proxy only on testnet/mainnet - if (chainId !== "31337") { - const instance = await deployments.get("FathomBridge"); - await fathomProxyFactoryContract.createProxy(formatBytes32String("FathomBridge"), instance.address, fathomProxyAdminAddress, "0x"); - } } module.exports = { diff --git a/scripts/setup/deploy/initialize.js b/scripts/setup/deploy/initialize.js index 9640814d..ff5b2a93 100644 --- a/scripts/setup/deploy/initialize.js +++ b/scripts/setup/deploy/initialize.js @@ -43,14 +43,6 @@ async function initialize(deployments, getChainId, forFixture = false) { const simplePriceFeed = await getProxy(proxyFactory, "SimplePriceFeed"); const slidingWindowDexOracle = await getProxy(proxyFactory, "SlidingWindowDexOracle"); - let fathomBridge; - if (chainId !== "31337") { - // Get FathomBridge Proxy only on testnet/mainnet - fathomBridge = await getProxy(proxyFactory, "FathomBridge"); - } else { - fathomBridge = null; - } - const fathomStablecoinProxyActions = await ethers.getContractAt("FathomStablecoinProxyActions", FathomStablecoinProxyActions.address); const addresses = getAddresses(chainId); @@ -124,12 +116,6 @@ async function initialize(deployments, getChainId, forFixture = false) { await simplePriceFeed.initialize(accessControlConfig.address); // await slidingWindowDexOracle.initialize(addresses.DEXFactory, 1800, 15); - // Initialize FathomBridge Proxy only on testnet/mainnet - if (chainId !== "31337") { - await fathomBridge.initialize(addresses.AsterizmInitializerLib, fathomStablecoin.address, accessControlConfig.address); - console.log("FathomBridge initialized"); - } - const newAddresses = { proxyFactory: proxyFactory.address, proxyAdmin: proxyAdmin.address, @@ -160,13 +146,8 @@ async function initialize(deployments, getChainId, forFixture = false) { proxyActionsStorage: proxyActionsStorage.address, fathomProxyAdmin: proxyAdmin.address, slidingWindowDexOracle: slidingWindowDexOracle.address, - // fathomBridge: fathomBridge.address, }; - if (chainId !== "31337") { - newAddresses.fathomBridge = fathomBridge.address; - } - fs.writeFileSync("./addresses.json", JSON.stringify(newAddresses)); } diff --git a/test/integration/ShowStopper.test.js b/test/integration/ShowStopper.test.js index eeb2e772..72408beb 100644 --- a/test/integration/ShowStopper.test.js +++ b/test/integration/ShowStopper.test.js @@ -51,7 +51,6 @@ describe("ShowStopper", () => { systemDebtEngine = await getProxy(proxyFactory, "SystemDebtEngine"); priceOracle = await getProxy(proxyFactory, "PriceOracle"); showStopper = await getProxy(proxyFactory, "ShowStopper"); - const mockFathomBridge = await smock.fake("MockFathomBridge"); accessControlConfig = await getProxy(proxyFactory, "AccessControlConfig"); const collateralPoolConfig = await getProxy(proxyFactory, "CollateralPoolConfig"); collateralTokenAdapter = await getProxy(proxyFactory, "CollateralTokenAdapter"); @@ -64,11 +63,6 @@ describe("ShowStopper", () => { const proxyWalletRegistry = await getProxy(proxyFactory, "ProxyWalletRegistry"); await proxyWalletRegistry.setDecentralizedMode(true); - await showStopper.setFathomBridge(mockFathomBridge.address); - mockFathomBridge.totalBridgedInAmount.returns(0); - mockFathomBridge.totalBridgedOutAmount.returns(0); - mockFathomBridge.cage.returns(); - ({ proxyWallets: [aliceProxyWallet, bobProxyWallet], } = await createProxyWallets([AliceAddress, BobAddress])); diff --git a/test/unit/fathom-bridge/FathomBridge.test.js b/test/unit/fathom-bridge/FathomBridge.test.js deleted file mode 100644 index 327c4512..00000000 --- a/test/unit/fathom-bridge/FathomBridge.test.js +++ /dev/null @@ -1,235 +0,0 @@ -const { ethers } = require("hardhat"); -const { expect } = require("chai"); -const { smock } = require("@defi-wonderland/smock"); - -const { WeiPerRad, WeiPerWad } = require("../../helper/unit"); -const { formatBytes32String } = ethers.utils; - -describe("FathomBridge", () => { - let mockedAccessControlConfig; - let fathomBridge; - let mockedToken; - let DeployerAddress; - let AliceAddress; - let AddressZero; - - beforeEach(async () => { - const { deployer, allice, a0 } = await getNamedAccounts(); - DeployerAddress = deployer; - AliceAddress = allice; - AddressZero = a0; - - mockedAccessControlConfig = await smock.fake("AccessControlConfig"); - mockedToken = await smock.fake("ERC20MintableStableSwap"); - - mockedAccessControlConfig.OWNER_ROLE.returns(formatBytes32String("OWNER_ROLE")); - mockedAccessControlConfig.MINTABLE_ROLE.returns(formatBytes32String("MINTABLE_ROLE")); - mockedAccessControlConfig.GOV_ROLE.returns(formatBytes32String("GOV_ROLE")); - mockedAccessControlConfig.SHOW_STOPPER_ROLE.returns(formatBytes32String("SHOW_STOPPER_ROLE")); - mockedAccessControlConfig.hasRole.returns(true); - mockedToken.transfer.returns(true); - mockedToken.transferFrom.returns(true); - mockedToken.balanceOf.returns(WeiPerRad); - mockedToken.approve.returns(true); - mockedToken.mint.returns(); - // No burn fn on ERC20MintableStableSwap - // mockedToken.burn.returns(); - - const FathomBridge = await ethers.getContractFactory("MockFathomBridge"); - fathomBridge = await FathomBridge.deploy(); - await fathomBridge.deployed(); - - await fathomBridge.initialize(mockedToken.address, mockedAccessControlConfig.address); - }); - - describe("#addToWhitelist", () => { - context("when the caller is not the owner", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(false); - await expect(fathomBridge.addToWhitelist(AliceAddress)).to.be.revertedWith("!(ownerRole or govRole)"); - }); - }); - context("when the caller is the owner", async () => { - it("should work", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await expect(fathomBridge.addToWhitelist(AliceAddress)).to.be.emit(fathomBridge, "LogAddToWhitelist").withArgs(AliceAddress); - }); - }); - context("when the caller is the owner but trying to add ZeroAddress", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await expect(fathomBridge.addToWhitelist(AddressZero)).to.be.revertedWith("FathomBridge/zero-address"); - }); - }); - }); - - describe("#removeFromWhitelist", () => { - context("when the caller is not the owner", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(false); - await expect(fathomBridge.removeFromWhitelist(AliceAddress)).to.be.revertedWith("!(ownerRole or govRole)"); - }); - }); - context("when the caller is the owner", async () => { - it("should work", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await fathomBridge.addToWhitelist(AliceAddress); - await expect(fathomBridge.removeFromWhitelist(AliceAddress)).to.be.emit(fathomBridge, "LogRemoveFromWhitelist").withArgs(AliceAddress); - }); - }); - context("when the caller is the owner but trying to add ZeroAddress", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await expect(fathomBridge.removeFromWhitelist(AddressZero)).to.be.revertedWith("FathomBridge/zero-address"); - }); - }); - }); - - describe("#setDecentralizedMode", () => { - context("when the caller is not the owner", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(false); - await expect(fathomBridge.setDecentralizedMode(true)).to.be.revertedWith("!(ownerRole or govRole)"); - }); - }); - context("when the caller is the owner", async () => { - it("should work", async () => { - mockedAccessControlConfig.hasRole.returns(true); - const decentralizedModeBefore = await fathomBridge.isDecentralizedMode(); - expect(decentralizedModeBefore).to.be.equal(false); - await expect(fathomBridge.setDecentralizedMode(true)).to.be.emit(fathomBridge, "LogSetDecentralizedMode").withArgs(true); - const decentralizedModeAfter = await fathomBridge.isDecentralizedMode(); - expect(decentralizedModeAfter).to.be.equal(true); - }); - }); - }); - - describe("#setFee", () => { - context("when the caller is not the owner", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(false); - await expect(fathomBridge.setFee(WeiPerRad)).to.be.revertedWith("!(ownerRole or govRole)"); - }); - }); - context("when the caller is the owner", async () => { - it("should work", async () => { - mockedAccessControlConfig.hasRole.returns(true); - const feeBefore = await fathomBridge.fixedBridgeFee(); - expect(feeBefore).to.be.equal(0); - await expect(fathomBridge.setFee(WeiPerRad)).to.be.emit(fathomBridge, "LogSetFee").withArgs(WeiPerRad); - const feeAfter = await fathomBridge.fixedBridgeFee(); - expect(feeAfter).to.be.equal(WeiPerRad); - }); - }); - }); - - describe("#withdrawFees", () => { - context("when the caller is not the owner", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(false); - await expect(fathomBridge.withdrawFees(AliceAddress)).to.be.revertedWith("!(ownerRole or govRole)"); - }); - }); - context("when the caller is the owner", async () => { - it("should work", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await expect(fathomBridge.withdrawFees(AliceAddress)) - .to.be.emit(fathomBridge, "LogWithdrawFees") - .withArgs(DeployerAddress, AliceAddress, WeiPerRad); - }); - }); - context("when the caller is the owner but withdraw fee to ZeroAddress", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await expect(fathomBridge.withdrawFees(AddressZero)).to.be.revertedWith("FathomBridge/zero-address"); - }); - }); - }); - - describe("#crossChainTransfer", () => { - context("when the caller is not whitelisted", async () => { - it("should revert", async () => { - await fathomBridge.removeFromWhitelist(DeployerAddress); - await expect(fathomBridge.crossChainTransfer(5522, AliceAddress, WeiPerWad)).to.be.revertedWith("FathomBridge/not-whitelisted"); - }); - }); - context("when the caller is the whitelisted", async () => { - it("should work and emit LogCrossChainTransferOut", async () => { - await fathomBridge.addToWhitelist(DeployerAddress); - await expect(fathomBridge.crossChainTransfer(5522, AliceAddress, WeiPerWad)) - .to.be.emit(fathomBridge, "LogCrossChainTransferOut") - .withArgs(5522, DeployerAddress, AliceAddress, WeiPerWad, 1); - }); - }); - context("when the caller is the whitelisted", async () => { - it("should work and emit LogFeeCollection", async () => { - await fathomBridge.addToWhitelist(DeployerAddress); - await expect(fathomBridge.crossChainTransfer(5522, AliceAddress, WeiPerWad)) - .to.be.emit(fathomBridge, "LogFeeCollection") - .withArgs(DeployerAddress, 0, 1); - }); - }); - context("when the caller is the whitelisted but try to send to ZeroAddress", async () => { - it("should revert", async () => { - await fathomBridge.addToWhitelist(DeployerAddress); - await expect(fathomBridge.crossChainTransfer(5522, AddressZero, WeiPerWad)).to.be.revertedWith("FathomBridge/zero-address"); - }); - }); - context("when the caller is the whitelisted and fee is set", async () => { - it("should work and emit LogFeeCollection", async () => { - await fathomBridge.addToWhitelist(DeployerAddress); - const feeBefore = await fathomBridge.fixedBridgeFee(); - expect(feeBefore).to.be.equal(0); - await fathomBridge.setFee(WeiPerWad); - const feeAfter = await fathomBridge.fixedBridgeFee(); - expect(feeAfter).to.be.equal(WeiPerWad); - await expect(fathomBridge.crossChainTransfer(5522, AliceAddress, WeiPerRad)) - .to.be.emit(fathomBridge, "LogFeeCollection") - .withArgs(DeployerAddress, WeiPerWad, 1); - }); - }); - }); - - describe("#Cage", () => { - context("when the caller is not the owner", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(false); - await expect(fathomBridge.cage()).to.be.revertedWith("!(ownerRole or showStopperRole)"); - }); - }); - context("when the caller is the owner", async () => { - it("should work", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await expect(fathomBridge.cage()).to.be.emit(fathomBridge, "LogCage"); - }); - }); - }); - describe("#pause", () => { - context("when the caller is not the owner", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(false); - await expect(fathomBridge.pause()).to.be.revertedWith("!(ownerRole or govRole)"); - }); - }); - context("when the caller is the owner", async () => { - it("should work", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await fathomBridge.pause(); - }); - }); - }); - describe("#unpause", () => { - context("when the caller is not the owner", async () => { - it("should revert", async () => { - mockedAccessControlConfig.hasRole.returns(false); - await expect(fathomBridge.unpause()).to.be.revertedWith("!(ownerRole or govRole)"); - }); - }); - context("when the caller is the owner", async () => { - it("should work", async () => { - mockedAccessControlConfig.hasRole.returns(true); - await fathomBridge.pause(); - }); - }); - }); -});