Skip to content

Commit

Permalink
address audit comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Spablob committed Jun 29, 2023
1 parent 9a7c788 commit e9bc1fd
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 79 deletions.
8 changes: 0 additions & 8 deletions contracts/libraries/VaultLifecycleTreasury.sol
Original file line number Diff line number Diff line change
Expand Up @@ -742,14 +742,6 @@ library VaultLifecycleTreasury {
);
require(bytes(_initParams._tokenName).length > 0, "!_tokenName");
require(bytes(_initParams._tokenSymbol).length > 0, "!_tokenSymbol");
require(
(_initParams._period == 7) ||
(_initParams._period == 14) ||
(_initParams._period == 30) ||
(_initParams._period == 90) ||
(_initParams._period == 180),
"!_period"
);
require(
_initParams._optionsPremiumPricer != address(0),
"!_optionsPremiumPricer"
Expand Down
51 changes: 29 additions & 22 deletions contracts/vaults/TreasuryVault/RibbonAutocallVault.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity =0.8.4;

import {SafeMath} from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {
SafeERC20
} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {AutocallVaultStorage} from "../../storage/AutocallVaultStorage.sol";
import {
VaultLifecycleTreasury
Expand Down Expand Up @@ -112,19 +108,21 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {

require(_autocallSeller != address(0), "A7");

uint256 currentPeriod = period;

// Observation frequency must evenly divide the period
require(_obsFreq > 0 && (period * 1 days) % _obsFreq == 0, "A8");
require(_obsFreq > 0 && (currentPeriod * 1 days) % _obsFreq == 0, "A8");

putOption.nOptionType = _optionType;
couponState.nCouponType = _couponState.couponType;
couponState.nAB = _couponState.AB;
couponState.nCB = _couponState.CB;

nObsFreq = _obsFreq;
nPeriod = period;
nPeriod = currentPeriod;
autocallSeller = _autocallSeller;
nAutocallSeller = _autocallSeller;
numTotalObs = (period * 1 days) / _obsFreq;
numTotalObs = (currentPeriod * 1 days) / _obsFreq;
}

/**
Expand Down Expand Up @@ -204,7 +202,7 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {
onlyOwner
{
require(_period > 0, "A9");
require(_obsFreq > 0 && (period * 1 days) % _obsFreq == 0, "A8");
require(_obsFreq > 0 && (_period * 1 days) % _obsFreq == 0, "A8");

emit PeriodAndObsFreqSet(obsFreq, _obsFreq, period, _period);

Expand Down Expand Up @@ -311,7 +309,7 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {
_setReserveRatio(_putOption.nOptionType, _spotPrice, _strikePrice);

// Set next option payoff
putOption.payoff = _setPutOptionPayoff(
putOption.payoff = _getPutOptionPayoff(
_putOption.nOptionType,
_spotPrice,
_strikePrice
Expand Down Expand Up @@ -349,13 +347,13 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {
}

/**
* @dev Sets the option payoff
* @dev Gets the option payoff
* @param _nOptionType is the type of the next option
* @param _price is the spot price of the new option
* @param _nextStrikePrice is the strike price of the next option
* @return payoff is the enhanced payoff amount
*/
function _setPutOptionPayoff(
function _getPutOptionPayoff(
OptionType _nOptionType,
uint256 _price,
uint256 _nextStrikePrice
Expand All @@ -371,12 +369,12 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {

if (_nOptionType == OptionType.DIP) {
payoff = _price - _nextStrikePrice;
}

uint256 decimals = vaultParams.decimals;
payoff = decimals > Vault.OTOKEN_DECIMALS
? payoff * 10**(decimals - Vault.OTOKEN_DECIMALS)
: payoff / 10**(Vault.OTOKEN_DECIMALS - decimals);
}
}

/**
Expand All @@ -396,9 +394,11 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {
uint256 returnAmt
)
{
uint256 currentReserveRatio = reserveRatio;

uint256 nonLockedAmt =
(vaultState.lockedAmount * reserveRatio) /
(10**Vault.OTOKEN_DECIMALS - reserveRatio);
(vaultState.lockedAmount * currentReserveRatio) /
(10**Vault.OTOKEN_DECIMALS - currentReserveRatio);

uint256 totalPremium =
IERC20(vaultParams.asset).balanceOf(address(this)) -
Expand All @@ -417,9 +417,11 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {
* means autocall barrier has been hit and we get all previous
* coupons
*/
CouponType currentCouponType = couponState.couponType;

bool hasMemory =
(couponState.couponType == CouponType.PHOENIX_MEMORY ||
couponState.couponType == CouponType.VANILLA)
(currentCouponType == CouponType.PHOENIX_MEMORY ||
currentCouponType == CouponType.VANILLA)
? true
: false;
nCouponsEarned = hasMemory ? lastCBBreach : nCBBreaches;
Expand Down Expand Up @@ -447,14 +449,16 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {
return (0, 0, 0);
}

uint256 startTS = _expiry - (numTotalObs - 1) * obsFreq;
uint256 currentObsFreq = obsFreq;

uint256 startTS = _expiry - (numTotalObs - 1) * currentObsFreq;
(, uint256 lastTS) = _lastObservation(_expiry);
address underlying = vaultParams.underlying;

autocallTS = _expiry;

// For every previous observation timestamp
for (uint256 ts = startTS; ts <= lastTS; ts += obsFreq) {
for (uint256 ts = startTS; ts <= lastTS; ts += currentObsFreq) {
uint256 obsPrice = ORACLE.getExpiryPrice(underlying, ts);
require(obsPrice > 0, "A12");
// If coupon barrier breached
Expand All @@ -477,7 +481,7 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {

// Convert to index
if (lastCBBreach > 0) {
lastCBBreach = numTotalObs - (_expiry - lastCBBreach) / obsFreq;
lastCBBreach = numTotalObs - (_expiry - lastCBBreach) / currentObsFreq;
}
}

Expand All @@ -492,14 +496,17 @@ contract RibbonAutocallVault is RibbonTreasuryVaultLite, AutocallVaultStorage {
view
returns (uint256 index, uint256 ts)
{
uint256 currentObsFreq = obsFreq;
uint256 currentNumTotalObs = numTotalObs;

index =
numTotalObs -
currentNumTotalObs -
(
_expiry > block.timestamp
? (_expiry - block.timestamp + obsFreq) / obsFreq
? (_expiry - block.timestamp + currentObsFreq) / currentObsFreq
: 0
);
ts = _expiry - (numTotalObs - index) * obsFreq;
ts = _expiry - (currentNumTotalObs - index) * currentObsFreq;
}

/**
Expand Down
51 changes: 21 additions & 30 deletions contracts/vaults/TreasuryVault/RibbonTreasuryVault.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity =0.8.4;

import {SafeMath} from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {
SafeERC20
Expand Down Expand Up @@ -35,7 +34,6 @@ contract RibbonTreasuryVault is
RibbonTreasuryVaultStorage
{
using SafeERC20 for IERC20;
using SafeMath for uint256;
using ShareMath for Vault.DepositReceipt;

/************************************************
Expand Down Expand Up @@ -149,13 +147,6 @@ contract RibbonTreasuryVault is
uint256 round
);

event InitiateGnosisAuction(
address indexed auctioningToken,
address indexed biddingToken,
uint256 auctionCounter,
address indexed manager
);

/************************************************
* CONSTRUCTOR & INITIALIZATION
***********************************************/
Expand Down Expand Up @@ -294,7 +285,7 @@ contract RibbonTreasuryVault is
: WEEKS_PER_YEAR / (_period / 7);

// We are dividing annualized management fee by num weeks in a year
return _managementFee.mul(Vault.FEE_MULTIPLIER).div(feeDivider);
return _managementFee * Vault.FEE_MULTIPLIER / feeDivider;
}

/**
Expand Down Expand Up @@ -487,11 +478,11 @@ contract RibbonTreasuryVault is
*/
function _depositFor(uint256 amount, address creditor) private {
uint256 currentRound = vaultState.round;
uint256 totalWithDepositedAmount = totalBalance().add(amount);
uint256 totalWithDepositedAmount = totalBalance() + (amount);

Vault.DepositReceipt memory depositReceipt = depositReceipts[creditor];
uint256 totalUserDeposit =
accountVaultBalance(msg.sender).add(depositReceipt.amount).add(
accountVaultBalance(msg.sender) + (depositReceipt.amount) + (
amount
);

Expand All @@ -516,7 +507,7 @@ contract RibbonTreasuryVault is

// If we have a pending deposit in the current round, we add on to the pending deposit
if (currentRound == depositReceipt.round) {
uint256 newAmount = uint256(depositReceipt.amount).add(amount);
uint256 newAmount = uint256(depositReceipt.amount) + (amount);
depositAmount = newAmount;
}

Expand All @@ -528,7 +519,7 @@ contract RibbonTreasuryVault is
unredeemedShares: uint128(unredeemedShares)
});

uint256 newTotalPending = uint256(vaultState.totalPending).add(amount);
uint256 newTotalPending = uint256(vaultState.totalPending) + (amount);
ShareMath.assertUint128(newTotalPending);

vaultState.totalPending = uint128(newTotalPending);
Expand Down Expand Up @@ -563,7 +554,7 @@ contract RibbonTreasuryVault is

uint256 withdrawalShares;
if (withdrawalIsSameRound) {
withdrawalShares = existingShares.add(numShares);
withdrawalShares = existingShares + (numShares);
} else {
require(existingShares == 0, "Existing withdraw");
withdrawalShares = numShares;
Expand All @@ -584,15 +575,15 @@ contract RibbonTreasuryVault is
);

if (userBalance > withdrawAmount) {
uint256 totalDeposit = userBalance.sub(withdrawAmount);
uint256 totalDeposit = userBalance - (withdrawAmount);
require(totalDeposit >= minDeposit, "Minimum deposit not reached");
}

ShareMath.assertUint128(withdrawalShares);
withdrawals[msg.sender].shares = uint128(withdrawalShares);

uint256 newQueuedWithdrawShares =
uint256(vaultState.queuedWithdrawShares).add(numShares);
uint256(vaultState.queuedWithdrawShares) + (numShares);
ShareMath.assertUint128(newQueuedWithdrawShares);
vaultState.queuedWithdrawShares = uint128(newQueuedWithdrawShares);

Expand Down Expand Up @@ -621,7 +612,7 @@ contract RibbonTreasuryVault is
// We leave the round number as non-zero to save on gas for subsequent writes
withdrawals[msg.sender].shares = 0;
vaultState.queuedWithdrawShares = uint128(
uint256(vaultState.queuedWithdrawShares).sub(withdrawalShares)
uint256(vaultState.queuedWithdrawShares) - (withdrawalShares)
);

uint256 withdrawAmount =
Expand Down Expand Up @@ -692,7 +683,7 @@ contract RibbonTreasuryVault is

ShareMath.assertUint128(numShares);
depositReceipts[msg.sender].unredeemedShares = uint128(
unredeemedShares.sub(numShares)
unredeemedShares - (numShares)
);

emit Redeem(msg.sender, numShares, depositReceipt.round);
Expand All @@ -716,20 +707,20 @@ contract RibbonTreasuryVault is
require(receiptAmount >= amount, "Exceed amount");

uint256 userBalance =
accountVaultBalance(msg.sender).add(receiptAmount);
accountVaultBalance(msg.sender) + (receiptAmount);

if (userBalance > amount) {
uint256 totalUserDeposit = userBalance.sub(amount);
uint256 totalUserDeposit = userBalance - (amount);
require(
totalUserDeposit >= minDeposit,
"Minimum deposit not reached"
);
}

// Subtraction underflow checks already ensure it is smaller than uint104
depositReceipt.amount = uint104(receiptAmount.sub(amount));
depositReceipt.amount = uint104(receiptAmount - (amount));
vaultState.totalPending = uint128(
uint256(vaultState.totalPending).sub(amount)
uint256(vaultState.totalPending) - (amount)
);

emit InstantWithdraw(msg.sender, amount, currentRound);
Expand All @@ -747,7 +738,7 @@ contract RibbonTreasuryVault is
function completeWithdraw() external nonReentrant {
uint256 withdrawAmount = _completeWithdraw();
lastQueuedWithdrawAmount = uint128(
uint256(lastQueuedWithdrawAmount).sub(withdrawAmount)
uint256(lastQueuedWithdrawAmount) - (withdrawAmount)
);
}

Expand Down Expand Up @@ -891,7 +882,7 @@ contract RibbonTreasuryVault is
currentOtokenPremium = uint104(premium);
optionState.nextOption = otokenAddress;

uint256 nextOptionReady = block.timestamp.add(DELAY);
uint256 nextOptionReady = block.timestamp + (DELAY);
require(
nextOptionReady <= type(uint32).max,
"Overflow nextOptionReady"
Expand Down Expand Up @@ -990,7 +981,7 @@ contract RibbonTreasuryVault is
);

vaultState.lockedAmount = uint104(
uint256(vaultState.lockedAmount).sub(unlockedAssetAmount)
uint256(vaultState.lockedAmount) - (unlockedAssetAmount)
);
}

Expand Down Expand Up @@ -1038,7 +1029,7 @@ contract RibbonTreasuryVault is
function _chargePerformanceFee(IERC20 token, uint256 amount) internal {
address recipient = feeRecipient;
uint256 transferAmount =
amount.mul(performanceFee).div(100 * Vault.FEE_MULTIPLIER);
amount * (performanceFee) / (100 * Vault.FEE_MULTIPLIER);

token.safeTransfer(recipient, transferAmount);

Expand All @@ -1064,7 +1055,7 @@ contract RibbonTreasuryVault is
// Distribute to depositors proportional to the amount of
// shares they own
address depositorAddress = _depositors[i];
_amounts[i] = shares(depositorAddress).mul(amount).div(totalSupply);
_amounts[i] = shares(depositorAddress) * (amount) / (totalSupply);

token.safeTransfer(depositorAddress, _amounts[i]);
}
Expand Down Expand Up @@ -1114,7 +1105,7 @@ contract RibbonTreasuryVault is
*/
function shares(address account) public view returns (uint256) {
(uint256 heldByAccount, uint256 heldByVault) = shareBalances(account);
return heldByAccount.add(heldByVault);
return heldByAccount + (heldByVault);
}

/**
Expand Down Expand Up @@ -1163,7 +1154,7 @@ contract RibbonTreasuryVault is
*/
function totalBalance() public view returns (uint256) {
return
uint256(vaultState.lockedAmount).add(
uint256(vaultState.lockedAmount) + (
IERC20(vaultParams.asset).balanceOf(address(this))
);
}
Expand Down
Loading

0 comments on commit e9bc1fd

Please sign in to comment.