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

Improvements to the mintDebt and repayDebt functions in stBTC contract #723

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

nkuba
Copy link
Member

@nkuba nkuba commented Sep 6, 2024

Fix returns in mintDebt and repayDebt functions (4f67f03)

The mintDebt and repayDebt functions are expected to return the amount of assets calculated based on the provided amount of shares:

) public whenNotPaused returns (uint256 assets) {

but they were returning the amount of shares instead:

return shares;

We fix this problem and add tests to cover these cases.

Fix rounding of shares to assets conversions in debt minting (490b179)

Previously, the shares-to-assets conversion was rounding down, which could have resulted in the minted debt being against the vault's interest.

Suppose a scenario where the vault has a 10% loss, meaning that each share is worth 0.9 assets.
If a user mints 1 share, the debt registered due to rounding down would be 0.
This can be used in a griefing attack, where a user could mint shares without registering debt.

To fix the issue, we now round up the shares to assets conversion in the mintDebt function.

Additionally, for the repayDebt function, we keep rounding down the shares to assets to avoid the opposite issue, where a user could repay more debt than they should.

It may happen that conversion in repayDebt returns 0, which should be validated by the caller. Since the interface used by the Mezo Portal contract burnReceipt function doesn't consider the return value of repayDebt, we are performing the validation in the burnReceipt function. We added a similar validation in the mintReceipt function for consistency.

The functions mintDebt and repayDebt are expected to return the amount
of assets calculated based on the provided amount of shares:
```
) public whenNotPaused returns (uint256 assets) {
```
but they were returning the amount of shares instead:
```
return shares;
```
Here we fix this problem and add tests to cover these cases.
Previously, the shares to assets conversion was rounding down, which could lead
to a situation where the minted debt was against the vault's interest.

Let's imagine a scenario where the vault has a 10% loss, meaning that each
share is worth 0.9 assets.
If a user mints 1 share, the debt registered due to rounding down would
be 0. This can be used as a griefing attack, where a user could mint shares
without registering any debt.

To fix the issue, we now round up the shares to assets conversion in mintDebt
function.

Additionally, for the repayDebt function, we keep rounding down the shares to assets
to avoid the opposite issue, where a user could repay more debt than they should.

It may happen that conversion in `repayDebt` returns `0`, and it should be
validated by the caller. Since, the interface used by the Mezo Portal contract
`burnReceipt` function doesn't consider the return value of `repayDebt`, we
are performing the validation in the `burnReceipt` function. For consistency
we added a similar validation in the `mintReceipt` function.
These tests are covering changes from 490b179
We also add tests to verify conversions in case of vault registering a loss.
@nkuba nkuba self-assigned this Sep 6, 2024
Copy link

netlify bot commented Sep 6, 2024

Deploy Preview for acre-dapp-testnet canceled.

Name Link
🔨 Latest commit 2f87ece
🔍 Latest deploy log https://app.netlify.com/sites/acre-dapp-testnet/deploys/66db0022d137f50008e44af8

Copy link

netlify bot commented Sep 6, 2024

Deploy Preview for acre-dapp canceled.

Name Link
🔨 Latest commit 2f87ece
🔍 Latest deploy log https://app.netlify.com/sites/acre-dapp/deploys/66db0022c7b27300084f0b7a

Comment on lines +338 to +341
uint256 assets = mintDebt(amount, to);
if (assets == 0) {
revert ConvertedToZero(amount, assets);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So do I understand it correctly that in mintReceipt the ConvertedToZero error will be triggered when user will request too low amount of stBTC in the context of a given state of contract, right?

And alike - in burnReceipt user can trigger ConvertedToZero by requesting to burn a low amount of asset.

But what if that's all that was minted by this user? They will not be able to burn their stBTC?

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

Successfully merging this pull request may close these issues.

2 participants