hats-finance / Thorn-protocol-0x1286ecdac50215a366458a14968fbca4bd95067d

GNU General Public License v3.0
0 stars 0 forks source link

`StableSwapFactory` Cannot Control Pausing Mechanism of Deployed Contracts leading to unusable pause functionality #24

Open hats-bug-reporter[bot] opened 1 month ago

hats-bug-reporter[bot] commented 1 month ago

Github username: -- Twitter username: -- Submission hash (on-chain): 0xcbef958a87b140b00599fd3e2efd567c564719226799eb3048bb3e7950ea672a Severity: low

Description: Description

The StableSwapFactory contract interacts with other contracts like StableSwapLPFactory and the deployer contracts (e.g., StableSwapTwoPoolDeployer). These contracts have functions such as createSwapLP and createSwapPair that are protected by the onlyOwner modifier, meaning only the owner of those contracts can invoke them. As a result, the StableSwapFactory contract needs the ownership of those contracts so that it will be able to call those functions.

Moreover, those contracts also implement a pausing mechanism via OpenZeppelin’s Pausable contract, allowing the owner to pause and unpause certain operations during emergency scenarios. However, the StableSwapFactory lacks the necessary functions to trigger the pauseContract and unPauseContract functions in those contracts.

In StableSwapTwoPoolDeployer:

 /**
    * @notice  onlyOwner
    * @dev     pauseContract
    */
@>  function pauseContract() external onlyOwner(){ _pause();}

    /**
    * @notice  onlyOwner
    * @dev     unpauseContract
    */
@>  function unPauseContract() external onlyOwner(){ _unpause();}

    function createSwapPair(
        address _tokenA,
        address _tokenB,
        uint256 _A,
        uint256 _fee,
        uint256 _admin_fee,
        address _admin,
        address _LP
@>    ) external onlyOwner returns (address) {
        require(_tokenA != address(0) && _tokenB != address(0) && _tokenA != _tokenB, "Illegal token");
        (address t0, address t1) = sortTokens(_tokenA, _tokenB);
        address[N_COINS] memory coins = [t0, t1];
        // create swap contract
        bytes memory bytecode = type(StableSwapTwoPool).creationCode;
        bytes32 salt = keccak256(abi.encodePacked(t0, t1, msg.sender, block.timestamp, block.chainid));
        address swapContract;
        assembly {
            swapContract := create2(0, add(bytecode, 32), mload(bytecode), salt)
        }
        StableSwapTwoPool(swapContract).initialize(coins, _A, _fee, _admin_fee, _admin, _LP);

        return swapContract;
    }

In StableSwapFactory:

function createSwapPair(
        address _tokenA,
        address _tokenB,
        uint256 _A,
        uint256 _fee,
        uint256 _admin_fee
    ) external onlyAdmin {

        require(_tokenA != ZEROADDRESS && _tokenB != ZEROADDRESS && _tokenA != _tokenB, "Illegal token");
        (address t0, address t1) = sortTokens(_tokenA, _tokenB);
@>      address LP = LPFactory.createSwapLP(t0, t1, ZEROADDRESS, address(this));
@>      address swapContract = SwapTwoPoolDeployer.createSwapPair(t0, t1, _A, _fee, _admin_fee, msg.sender, LP);  
@>      IStableSwapLP(LP).setMinter(swapContract);
        addPairInfoInternal(swapContract, t0, t1, ZEROADDRESS, LP);
    }

Attachments

  1. Revised Code

Add functions to the StableSwapFactory that allow it to call the pauseContract and unPauseContract functions on the deployed contracts, ensuring full control over their pausing mechanisms.

omega-audits commented 1 month ago

It's a duplicate of #14