Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify no duplicate input tokens in GeneralConverter #104

Open
gpersoon opened this issue Oct 12, 2021 · 0 comments
Open

Verify no duplicate input tokens in GeneralConverter #104

gpersoon opened this issue Oct 12, 2021 · 0 comments

Comments

@gpersoon
Copy link

gpersoon commented Oct 12, 2021

Vulnerability details

If duplicate input tokens are used in GeneralConverter then the function Convert will go wrong.

Suppose tokens[0]==tokens[1] and tokens.length==2;
Suppose you call Convert(tokens[0],tokenCRV,100,...)
Then in the first pass of the for loop:
_input == tokens[0] ==> amounts[0]=100 ==> add_liquidity( amounts[]={100,0} )
In the second pass of the for loop:
_input == tokens[1] ==> amounts[1]=100 ==> add_liquidity( amounts[]={100,100} )

So add_liquidity is called twice.

As similar issue occurs when converting from tokenCRV:
Then "tokens[i].safeTransfer(msg.sender, _outputAmount);" will be called multiple times.

Proof of concept

function convert(
address _input,
address _output,
uint256 _inputAmount,
uint256 _estimatedOutput
) external override onlyAuthorized returns (uint256 _outputAmount) {
if (_output == address(tokenCRV)) {
// convert to CRV
for (uint8 i = 0; i < tokens.length; i++) {
if (_input == address(tokens[i])) {
uint256 _before = tokenCRV.balanceOf(address(this));
if (tokens.length == 2) {
uint256[2] memory amounts;
amounts[i] = _inputAmount;
ICurve2Pool(address(swapPool)).add_liquidity(
amounts,
_estimatedOutput
);
} else {
uint256[3] memory amounts;
amounts[i] = _inputAmount;
ICurve3Pool(address(swapPool)).add_liquidity(
amounts,
_estimatedOutput
);
}

Recommended mitigation steps

Check all input token addresses are different in the constructor of GeneralConverter.

You could use "indices[address(_tokens[i])]" for this, but then you have to add 1 to all these values to make sure 0 is never used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant