hats-finance / Convergence---Convex-integration-0xb3df23e155b74ad2b93777f58980d6727e8b40bb

0 stars 1 forks source link

Impossible to initialize multiple contracts due to mismatched cvgControlTower implementation #64

Open hats-bug-reporter[bot] opened 4 months ago

hats-bug-reporter[bot] commented 4 months ago

Github username: @jonsey Twitter username: rnemes4 Submission hash (on-chain): 0xefbc10313a3e38adcd61ce3f0b2cdd39a21222061d4dfa2f4b751f24cb0546c1 Severity: low

Description: Description\ The cvgControlTower implementation address is hard coded in the StakingServiceBase, but the deployed version of this contract does not have any implementations for cvxConvergenceLocker and cvxStakingPositionManager. These are only implemented in version 2 of the control tower. Which is not deployed at that address.

Attack Scenario\ With the address hardcode as it is now it will be impossible toi initialise the cvxConvergenceLocker. The situation is also the same for the following contracts CvgFraxLpStakingService CvxAssetStakingService

Attachments

  1. Proof of Concept (PoC) File The following Foundry test proves that the initialisation of the CvgCvxStakingPositionService will fail. Help can be provided in order to set up a foundry test suite if required.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Test, console} from "forge-std/Test.sol";

import "../lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "../lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol";

import {ICrvPoolPlain} from "../src/contracts/interfaces/ICrvPoolPlain.sol";
import {CvgCvxStakingPositionService, ICvx1} from "../src/contracts/Staking/Convex/cvgCVX/CvgCvxStakingPositionService.sol";

contract CvgCvxStakingPositionServiceTest is Test {
    uint256 mainnetFork;

    TransparentUpgradeableProxy proxy;
    ProxyAdmin admin;

    CvgCvxStakingPositionService public cvgCvxStakingPositionService;
    CvgCvxStakingPositionService public wrappedProxy;

    function setUp() public {
        mainnetFork = vm.createFork("eth");
        vm.selectFork(mainnetFork);

        admin = new ProxyAdmin();

        cvgCvxStakingPositionService = new CvgCvxStakingPositionService();

        proxy = new TransparentUpgradeableProxy(address(cvgCvxStakingPositionService), address(admin), "");

        wrappedProxy = CvgCvxStakingPositionService(address(proxy));
    }

    function test_Initialise() public {
        address _cvxConvergenceLocker = vm.addr(1);
        ICrvPoolPlain _curvePool = ICrvPoolPlain(vm.addr(2));
        ICvx1 _cvx = ICvx1(vm.addr(3));
        string memory _symbol = "CVXCRV";

        wrappedProxy.initialize(
            _cvxConvergenceLocker,
            _curvePool,
            _cvx,
            _symbol
        );

        assert(true);
    }
}

Output

Encountered a total of 1 failing tests, 0 tests succeeded
 % forge test -vvv                                                                                                                                                       current/convergencePOC (master ⚡) rnemes
[⠊] Compiling...
[⠊] Compiling 1 files with 0.8.25
[⠒] Solc 0.8.25 finished in 1.82s
Compiler run successful!

Ran 1 test for test/CvgCvxStakingPositionService.t.sol:CvgCvxStakingPositionServiceTest
[FAIL. Reason: EvmError: Revert] test_Initialise() (gas: 253645)
Traces:
  [253645] CvgCvxStakingPositionServiceTest::test_Initialise()
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69
    ├─ [244337] TransparentUpgradeableProxy::initialize(0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf, 0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF, 0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69, "CVXCRV")
    │   ├─ [237181] CvgCvxStakingPositionService::initialize(0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf, 0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF, 0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69, "CVXCRV") [delegatecall]
    │   │   ├─ [9699] 0xB0Afc8363b8F36E0ccE5D54251e20720FfaeaeE7::cvgCycle() [staticcall]
    │   │   │   ├─ [2404] 0xFd7ea97e967586B5DD79D23eae5a53A47B296E3E::cvgCycle() [delegatecall]
    │   │   │   │   └─ ← [Return] 14
    │   │   │   └─ ← [Return] 14
    │   │   ├─ [1074] 0xB0Afc8363b8F36E0ccE5D54251e20720FfaeaeE7::cvxRewardDistributor() [staticcall]
    │   │   │   ├─ [281] 0xFd7ea97e967586B5DD79D23eae5a53A47B296E3E::cvxRewardDistributor() [delegatecall]
    │   │   │   │   └─ ← [Revert] EvmError: Revert
    │   │   │   └─ ← [Revert] EvmError: Revert
    │   │   └─ ← [Revert] EvmError: Revert
    │   └─ ← [Revert] EvmError: Revert
    └─ ← [Revert] EvmError: Revert

Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 1.84s (696.57ms CPU time)

Ran 1 test suite in 1.89s (1.84s CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
  1. Revised Code File (Optional)

Add an initialize function to the stakingBaseController allowing the deployer to provide the address of the correct deployed version of the cvgControlTower and remove the hardcoded initialization.

function initialize(address cvgController) public initializer {
        __Ownable2Step_init();

        cvgControlTower = ICvgControlTowerV2(cvgController);
    }

Files:

Jonsey commented 4 months ago

Oops, ignore this submission. Obviously the cvgControlTower will be upgraded to version 2.