You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on May 26, 2023. It is now read-only.
Users will receive less than they expect from the borrow()
Summary
Alice will invoke borrow() with amount == X
He will receive only X - n
But updateLocked() will update locked with X value
Vulnerability Detail
On UToken.sol ==> borrow()
if (!assetManagerContract.withdraw(underlying, to, amount)) revertWithdrawFailed();
On AssetManager.sol ==> withdraw() in case isMarketSupported(token) is true
This loop will work
for (uint256 i =0; i < withdrawSeqLength && remaining >0; i++) {
IMoneyMarketAdapter moneyMarket = moneyMarkets[withdrawSeq[i]];
if (!moneyMarket.supportsToken(token)) continue;
uint256 supply = moneyMarket.getSupply(token);
if (supply ==0) continue;
uint256 withdrawAmount = supply < remaining ? supply : remaining;
remaining -= withdrawAmount;
moneyMarket.withdraw(token, account, withdrawAmount);
}
in case i == withdrawSeqLength and remaining > 0 this loop will stop. And there is no way to complete sending the remaining balace
The withdraw() will return True even if the remaining > 0
Now go back to UToken.sol ==> borrow()
if (!assetManagerContract.withdraw(underlying, to, amount)) revertWithdrawFailed();
IUserManager(userManager).updateLocked(msg.sender, uint96(amount + fee), true);
The first check will passed successfully
And the second line will update the locked amount to amount + fee even if the user dosen’t receive all the amount
Impact
The user will receive less amount of the locked
Code Snippet
if (isMarketSupported(token)) {
uint256 withdrawSeqLength = withdrawSeq.length;
// iterate markets according to defined sequence and withdrawfor (uint256 i =0; i < withdrawSeqLength && remaining >0; i++) {
IMoneyMarketAdapter moneyMarket = moneyMarkets[withdrawSeq[i]];
if (!moneyMarket.supportsToken(token)) continue;
uint256 supply = moneyMarket.getSupply(token);
if (supply ==0) continue;
uint256 withdrawAmount = supply < remaining ? supply : remaining;
remaining -= withdrawAmount;
moneyMarket.withdraw(token, account, withdrawAmount);
}
}
if (!assetManagerContract.withdraw(underlying, to, amount)) revertWithdrawFailed();
IUserManager(userManager).updateLocked(msg.sender, uint96(amount + fee), true);
Ch_301
medium
Users will receive less than they expect from the
borrow()
Summary
Alice will invoke
borrow()
withamount == X
He will receive only
X - n
But
updateLocked()
will update locked withX
valueVulnerability Detail
On
UToken.sol
==>borrow()
On
AssetManager.sol
==>withdraw()
in caseisMarketSupported(token)
istrue
This loop will work
in case
i == withdrawSeqLength
andremaining > 0
this loop will stop. And there is no way to complete sending theremaining
balaceThe
withdraw()
will returnTrue
even if theremaining > 0
Now go back to
UToken.sol
==>borrow()
The first check will passed successfully
And the second line will update the locked amount to
amount + fee
even if the user dosen’t receive all theamount
Impact
The user will receive less amount of the locked
Code Snippet
https://github.com/sherlock-audit/2022-10-union-finance/blob/main/union-v2-contracts/contracts/asset/AssetManager.sol#L345-L359
https://github.com/sherlock-audit/2022-10-union-finance/blob/main/union-v2-contracts/contracts/market/UToken.sol#L547-L552
Tool used
Manual Review
Recommendation
You can check
remaining
onwithdraw()
duplicate of #27
The text was updated successfully, but these errors were encountered: