Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

contracts/core/test/CurveMock.sol

The provided Solidity code for the CurveMock contract has a few potential vulnerabilities and areas of concern. Here’s a breakdown of the issues:

1. Reentrancy Vulnerability

While the exchange function does not currently have any external calls that could lead to reentrancy, it's important to keep in mind that if you ever add logic that calls an external contract, you should consider using a Reentrancy Guard or ensure that state changes happen before external calls.

2. Improper Handling of Token Transfers

The use of transferFrom and transfer is somewhat concerning:

  • Lack of Return Value Checks: The transferFrom and transfer functions from the IERC20 interface return a boolean indicating success or failure. You should check the return values to ensure that the operations were successful.

    require(tokens[i].transferFrom(msg.sender, address(this), _dx), "Transfer failed");
    require(tokens[j].transfer(_receiver, _dx), "Transfer failed");

3. Token Amount Validation

There is no check to ensure that _dx is a valid amount (greater than zero). Allowing a zero or negative value might not be appropriate:

require(_dx > 0, "Amount must be greater than zero");

4. Token Index Validation

The validation of token indices _i and _j uses require(_i < 2 && _j < 2), which is sufficient for the current implementation. However, if the contract ever becomes more complex or if you plan to expand it, consider using constants or enums for better maintainability.

5. Event Emission

The exchange function does not emit any events. It's generally a good practice to emit events for important state changes (like token exchanges) to allow external observers to track activity on the contract.

event TokensExchanged(address indexed sender, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut);

6. Gas Limit Concerns

If _dx is large and there is a potential for high gas consumption due to complex logic in token contracts, the transaction might fail. While not a vulnerability per se, it's something to consider in a real-world scenario.

7. Lack of Access Control

Currently, any user can call the exchange function. Depending on the intended use, you might want to restrict who can perform exchanges.

8. No Support for Fee or Slippage Mechanisms

In a real-world scenario, token swaps often include fees or slippage tolerances. Consider how to manage these in a more sophisticated implementation.

Summary

Here's a revised version of the exchange function with some of the suggested improvements:

function exchange(
int128 _i,
int128 _j,
uint256 _dx,
uint256,
address _receiver
) external returns (uint256) {
require(_i < 2 && _j < 2, "Invalid token indexes");
require(_i != _j, "Cannot send same token");
require(_dx > 0, "Amount must be greater than zero");
address receiver = _receiver != address(0) ? _receiver : msg.sender;
uint i = uint(_i);
uint j = uint(_j);
require(tokens[i].transferFrom(msg.sender, address(this), _dx), "Transfer failed");
require(tokens[j].transfer(receiver, _dx), "Transfer failed");
emit TokensExchanged(msg.sender, address(tokens[i]), address(tokens[j]), _dx, _dx);
return _dx;
}

Conclusion

Always ensure thorough testing and possibly an audit for production contracts, especially those handling token transfers and swaps, to mitigate any potential vulnerabilities.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.