Lucene search

K
code423n4Code4renaCODE423N4:2023-10-CANTO-FINDINGS-ISSUES-295
HistoryOct 06, 2023 - 12:00 a.m.

The Liquidity mining callpath sidecar owner can pull native tokens from the Dex

2023-10-0600:00:00
Code4rena
github.com
3
liquidity mining
sidecar
native tokens
dex
validation

6.7 Medium

AI Score

Confidence

High

Lines of code
<https://github.com/code-423n4/2023-10-canto/blob/40edbe0c9558b478c84336aaad9b9626e5d99f34/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol#L74&gt;

Vulnerability details

Impact

The owner of liquidity mining sidecar can pull the native coins that are stored in the CrocSwapDex to reward the users.

Proof of Concept

The setConcRewards and setAmbRewards functions doesn’t check if the quoted amount of rewards are actually sent by the caller. This allows the owner to specify any total amount of native coin which available in the CrocSwapDex from which the funds will be used when distributing the rewards.

    function setConcRewards(bytes32 poolIdx, uint32 weekFrom, uint32 weekTo, uint64 weeklyReward) public payable {
        // require(msg.sender == governance_, "Only callable by governance");
        require(weekFrom % WEEK == 0 && weekTo % WEEK == 0, "Invalid weeks");
        while (weekFrom &lt;= weekTo) {
            concRewardPerWeek_[poolIdx][weekFrom] = weeklyReward;
            weekFrom += uint32(WEEK);
        }
    }

<https://github.com/code-423n4/2023-10-canto/blob/40edbe0c9558b478c84336aaad9b9626e5d99f34/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol#L65C7-L72&gt;

    function setAmbRewards(bytes32 poolIdx, uint32 weekFrom, uint32 weekTo, uint64 weeklyReward) public payable {
        // require(msg.sender == governance_, "Only callable by governance");
        require(weekFrom % WEEK == 0 && weekTo % WEEK == 0, "Invalid weeks");
        while (weekFrom &lt;= weekTo) {
            ambRewardPerWeek_[poolIdx][weekFrom] = weeklyReward;
            weekFrom += uint32(WEEK);
        }
    }

<https://github.com/code-423n4/2023-10-canto/blob/40edbe0c9558b478c84336aaad9b9626e5d99f34/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol#L74-L81&gt;

According to Ambient Docs they allow for deposits in native tokens.

Demo

  1. Update TestLiquidityMining.js : The funds added using hardhat.setBalance() is being used by the owner to distribute rewards
diff --git a/canto_ambient/test_canto/TestLiquidityMining.js b/canto_ambient/test_canto/TestLiquidityMining.js
index bd21a32..b917308 100644
--- a/canto_ambient/test_canto/TestLiquidityMining.js
+++ b/canto_ambient/test_canto/TestLiquidityMining.js
@@ -7,6 +7,7 @@ const { time } = require("@nomicfoundation/hardhat-network-helpers");
 var keccak256 = require("@ethersproject/keccak256").keccak256;
 
 const chai = require("chai");
+const { network, ethers } = require("hardhat");
 const abi = new AbiCoder();
 
 const BOOT_PROXY_IDX = 0;
@@ -218,7 +219,6 @@ describe("Liquidity Mining Tests", function () {
 		);
 		tx = await dex.userCmd(2, mintConcentratedLiqCmd, {
 			gasLimit: 6000000,
-			value: ethers.utils.parseUnits("10", "ether"),
 		});
 		await tx.wait();
 
@@ -243,6 +243,17 @@ describe("Liquidity Mining Tests", function () {
 			BigNumber.from("999898351768")
 		);
 
+		let dexBal = await ethers.provider.getBalance(dex.address);
+		expect(dexBal.eq(0)).to.be.eq(true);
+
+		// dex gains native token from other methods
+		await network.provider.send("hardhat_setBalance", [
+			dex.address,
+			ethers.utils.parseEther("2").toHexString(),
+		  ]);
+		dexBal = await ethers.provider.getBalance(dex.address);
+		expect(dexBal.eq(ethers.utils.parseEther("2"))).to.be.eq(true);
+
 		//////////////////////////////////////////////////
 		// SET LIQUIDITY MINING REWARDS FOR CONCENTRATED LIQUIDITY
 		//////////////////////////////////////////////////

Tools Used

Hardhat

Recommended Mitigation Steps

Add a msg.value check in the rewards function to see that the total value is passed when call the functions.

diff --git a/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol b/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol
index e6c63f7..44dd338 100644
--- a/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol
+++ b/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol
@@ -65,6 +65,7 @@ contract LiquidityMiningPath is LiquidityMining {
     function setConcRewards(bytes32 poolIdx, uint32 weekFrom, uint32 weekTo, uint64 weeklyReward) public payable {
         // require(msg.sender == governance_, "Only callable by governance");
         require(weekFrom % WEEK == 0 && weekTo % WEEK == 0, "Invalid weeks");
+        require((1 +(weekTo - weekFrom) / WEEK) * weeklyReward == msg.value);
         while (weekFrom &lt;= weekTo) {
             concRewardPerWeek_[poolIdx][weekFrom] = weeklyReward;
             weekFrom += uint32(WEEK);

Assessed type

Rug-Pull


The text was updated successfully, but these errors were encountered:

All reactions

6.7 Medium

AI Score

Confidence

High