Skip to content
This repository has been archived by the owner on Dec 31, 2023. It is now read-only.

MohammedRizwan - In D3VaultFunding.sol and D3VaultLiquidation.sol contracts, Multiplication after Division can cause larger Precision loss #185

Closed
sherlock-admin opened this issue Jul 1, 2023 · 1 comment
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue Will Fix The sponsor confirmed this issue will be fixed

Comments

@sherlock-admin
Copy link
Contributor

sherlock-admin commented Jul 1, 2023

MohammedRizwan

high

In D3VaultFunding.sol and D3VaultLiquidation.sol contracts, Multiplication after Division can cause larger Precision loss

Summary

There are multiple instances in the D3VaultFunding.sol and D3VaultLiquidation.sol contracts code where multiplication is done after the division which is causing larger precision loss.

Vulnerability Detail

In D3VaultFunding.sol,

File: contracts/DODOV3MM/D3Vault/D3VaultFunding.sol

70    function poolBorrow(address token, uint256 amount) external nonReentrant allowedToken(token) onlyPool {
    
      // some code
79        uint256 usedQuota = record.amount.div(oldInterestIndex).mul(currentInterestIndex);         @audit // precision loss

     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultFunding.sol

94    function poolRepay(address token, uint256 amount) external nonReentrant allowedToken(token) onlyPool {
    
      // some code
99    uint256 borrows = record.amount.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(info.borrowIndex);   @audit // precision loss
     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultFunding.sol

117   function _poolRepayAll(address pool, address token) internal {
    
      // some code
122      uint256 amount = record.amount.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(info.borrowIndex);   @audit // precision loss
     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultFunding.sol

193    function getPoolLeftQuota(address pool, address token) public view returns(uint256 leftQuota) {
    
      // some code
198       uint256 usedQuota = assetInfo[token].borrowRecord[pool].amount.div(oldInterestIndex).mul(currentInterestIndex);   @audit // precision loss
     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultFunding.sol

239    function _getBalanceAndBorrows(address pool, address token) internal view returns (uint256, uint256) {
    
      // some code
244        uint256 borrows = record.amount.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(info.borrowIndex);   @audit // precision loss
     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultFunding.sol

250    function _getTotalDebtValue(address pool) internal view returns (uint256 totalDebt) {
    
      // some code
255            uint256 borrows = record.amount.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(info.borrowIndex);   @audit // precision loss
     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultFunding.sol

351    function getPoolBorrowAmount(address pool, address token) public view returns (uint256 amount) {
    
      // some code
354        amount = record.amount.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(borrowIndex);  @audit // precision loss
     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultFunding.sol

351    function getPoolBorrowAmount(address pool, address token) public view returns (uint256 amount) {
    
      // some code
354        amount = record.amount.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(borrowIndex);  @audit // precision loss
     // some code

In D3VaultFunding.sol,

File: contracts/DODOV3MM/D3Vault/D3VaultLiquidation.sol

30    function liquidate(

      // some code
53      uint256 borrows = record.amount.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(info.borrowIndex);   @audit // precision loss
     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultLiquidation.sol

65   function startLiquidation(address pool) external onlyLiquidator nonReentrant {

      // some code
82            uint256 debt = record.amount.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(info.borrowIndex).mul(ratio);   @audit // precision loss
     // some code
File: contracts/DODOV3MM/D3Vault/D3VaultLiquidation.sol

117    function finishLiquidation(address pool) external onlyLiquidator nonReentrant {

      // some code
144            uint256 realDebt = borrows.div(record.interestIndex == 0 ? 1e18 : record.interestIndex).mul(info.borrowIndex);   @audit // precision loss
     // some code

As seen above, the final calculated values of variables will result in precision loss because the division is happening first. Solidity does not support floating numbers and truncates it. For example, a value 0.75 will be truncated to 0. It is recommended to perform multiplication first and division at last.

Impact

Larger precision loss leading to wrong calculations

Code Snippet

Instance 1:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultFunding.sol#L79

Instance 2:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultFunding.sol#L99

Instance 3:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultFunding.sol#L122

Instance 4:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultFunding.sol#L198

Instance 5:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultFunding.sol#L244

Instance 6:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultFunding.sol#L255

Instance 7:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultFunding.sol#L354

Instance 8:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultLiquidation.sol#L53

Instance 9:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultLiquidation.sol#L82

Instance 10:
https://github.com/sherlock-audit/2023-06-dodo/blob/a8d30e611acc9762029f8756d6a5b81825faf348/new-dodo-v3/contracts/DODOV3MM/D3Vault/D3VaultLiquidation.sol#L144

Tool used

Manual Review

Recommendation

Recommend to perform the Multiplication first and division last.

Duplicate of #45

@github-actions github-actions bot closed this as completed Jul 5, 2023
@github-actions github-actions bot added Medium A valid Medium severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Jul 5, 2023
@traceurl traceurl added the Will Fix The sponsor confirmed this issue will be fixed label Jul 12, 2023
@sherlock-admin2 sherlock-admin2 added the Reward A payout will be made for this issue label Jul 24, 2023
@IAm0x52
Copy link
Collaborator

IAm0x52 commented Sep 8, 2023

Same issue as #45 and same fix PR

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue Will Fix The sponsor confirmed this issue will be fixed
Projects
None yet
Development

No branches or pull requests

4 participants