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

Fix Review #2

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 88 additions & 12 deletions mento-core/contracts/goodDollar/BancorExchangeProvider.sol
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
) external view virtual returns (uint256 amountOut) {
PoolExchange memory exchange = getPoolExchange(exchangeId);
uint256 scaledAmountIn = amountIn * tokenPrecisionMultipliers[tokenIn];

if (tokenIn == exchange.tokenAddress) {
require(scaledAmountIn < exchange.tokenSupply, "amountIn is greater than tokenSupply");
// apply exit contribution
scaledAmountIn = (scaledAmountIn * (MAX_WEIGHT - exchange.exitContribution)) / MAX_WEIGHT;
}

Comment on lines +125 to +131
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

Comment on lines +125 to +131
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

uint256 scaledAmountOut = _getScaledAmountOut(exchange, tokenIn, tokenOut, scaledAmountIn);
amountOut = scaledAmountOut / tokenPrecisionMultipliers[tokenOut];
return amountOut;
Expand All @@ -137,19 +144,27 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
PoolExchange memory exchange = getPoolExchange(exchangeId);
uint256 scaledAmountOut = amountOut * tokenPrecisionMultipliers[tokenOut];
uint256 scaledAmountIn = _getScaledAmountIn(exchange, tokenIn, tokenOut, scaledAmountOut);
amountIn = scaledAmountIn / tokenPrecisionMultipliers[tokenIn];

if (tokenIn == exchange.tokenAddress) {
// apply exit contribution
scaledAmountIn = (scaledAmountIn * MAX_WEIGHT) / (MAX_WEIGHT - exchange.exitContribution);
require(scaledAmountIn < exchange.tokenSupply, "amountIn is greater than tokenSupply");
}

Comment on lines +147 to +153
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

Comment on lines +147 to +153
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

amountIn = divAndRoundUp(scaledAmountIn, tokenPrecisionMultipliers[tokenIn]);
return amountIn;
}

/// @inheritdoc IBancorExchangeProvider
function currentPrice(bytes32 exchangeId) public view returns (uint256 price) {
// calculates: reserveBalance / (tokenSupply * reserveRatio)
require(exchanges[exchangeId].reserveAsset != address(0), "Exchange does not exist");
PoolExchange memory exchange = getPoolExchange(exchangeId);
uint256 scaledReserveRatio = uint256(exchange.reserveRatio) * 1e10;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#560.

Fixes issues: #23

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#560.

Fixes issues: #23

UD60x18 denominator = wrap(exchange.tokenSupply).mul(wrap(scaledReserveRatio));
price = unwrap(wrap(exchange.reserveBalance).div(denominator));
return price;
uint256 priceScaled = unwrap(wrap(exchange.reserveBalance).div(denominator));

price = priceScaled / tokenPrecisionMultipliers[exchange.reserveAsset];
Comment on lines +165 to +167
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#560.

Fixes issues: #23

Comment on lines +165 to +167
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#560.

Fixes issues: #23

}

/* ============================================================ */
Expand All @@ -165,9 +180,9 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B

/// @inheritdoc IBancorExchangeProvider
function setReserve(address _reserve) public onlyOwner {
require(address(_reserve) != address(0), "Reserve address must be set");
require(_reserve != address(0), "Reserve address must be set");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#545.

Fixes issues: #79

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#545.

Fixes issues: #79

reserve = IReserve(_reserve);
emit ReserveUpdated(address(_reserve));
emit ReserveUpdated(_reserve);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#545.

Fixes issues: #79

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#545.

Fixes issues: #79

}

/// @inheritdoc IBancorExchangeProvider
Expand Down Expand Up @@ -197,8 +212,21 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
) public virtual onlyBroker returns (uint256 amountOut) {
PoolExchange memory exchange = getPoolExchange(exchangeId);
uint256 scaledAmountIn = amountIn * tokenPrecisionMultipliers[tokenIn];
uint256 exitContribution = 0;

if (tokenIn == exchange.tokenAddress) {
require(scaledAmountIn < exchange.tokenSupply, "amountIn is greater than tokenSupply");
// apply exit contribution
exitContribution = (scaledAmountIn * exchange.exitContribution) / MAX_WEIGHT;
scaledAmountIn -= exitContribution;
}

Comment on lines +215 to +223
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

Comment on lines +215 to +223
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

uint256 scaledAmountOut = _getScaledAmountOut(exchange, tokenIn, tokenOut, scaledAmountIn);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

executeSwap(exchangeId, tokenIn, scaledAmountIn, scaledAmountOut);
if (exitContribution > 0) {
_accountExitContribution(exchangeId, exitContribution);
}
Comment on lines +227 to +229
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

Comment on lines +227 to +229
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64


amountOut = scaledAmountOut / tokenPrecisionMultipliers[tokenOut];
return amountOut;
Expand All @@ -214,9 +242,26 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
PoolExchange memory exchange = getPoolExchange(exchangeId);
uint256 scaledAmountOut = amountOut * tokenPrecisionMultipliers[tokenOut];
uint256 scaledAmountIn = _getScaledAmountIn(exchange, tokenIn, tokenOut, scaledAmountOut);

uint256 exitContribution = 0;
uint256 scaledAmountInWithExitContribution = scaledAmountIn;

if (tokenIn == exchange.tokenAddress) {
// apply exit contribution
scaledAmountInWithExitContribution = (scaledAmountIn * MAX_WEIGHT) / (MAX_WEIGHT - exchange.exitContribution);
require(
scaledAmountInWithExitContribution < exchange.tokenSupply,
"amountIn required is greater than tokenSupply"
);
exitContribution = scaledAmountInWithExitContribution - scaledAmountIn;
}

Comment on lines +245 to +258
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

Comment on lines +245 to +258
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

executeSwap(exchangeId, tokenIn, scaledAmountIn, scaledAmountOut);
if (exitContribution > 0) {
_accountExitContribution(exchangeId, exitContribution);
}
Comment on lines +260 to +262
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

Comment on lines +260 to +262
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64


amountIn = scaledAmountIn / tokenPrecisionMultipliers[tokenIn];
amountIn = divAndRoundUp(scaledAmountInWithExitContribution, tokenPrecisionMultipliers[tokenIn]);
return amountIn;
}

Expand All @@ -242,6 +287,9 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
tokenPrecisionMultipliers[exchange.reserveAsset] = 10 ** (18 - uint256(reserveAssetDecimals));
tokenPrecisionMultipliers[exchange.tokenAddress] = 10 ** (18 - uint256(tokenDecimals));

exchange.reserveBalance = exchange.reserveBalance * tokenPrecisionMultipliers[exchange.reserveAsset];
exchange.tokenSupply = exchange.tokenSupply * tokenPrecisionMultipliers[exchange.tokenAddress];

exchanges[exchangeId] = exchange;
exchangeIds.push(exchangeId);
emit ExchangeCreated(exchangeId, exchange.reserveAsset, exchange.tokenAddress);
Expand All @@ -262,7 +310,7 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B

function _setExitContribution(bytes32 exchangeId, uint32 exitContribution) internal {
require(exchanges[exchangeId].reserveAsset != address(0), "Exchange does not exist");
require(exitContribution <= MAX_WEIGHT, "Exit contribution is too high");
require(exitContribution < MAX_WEIGHT, "Exit contribution is too high");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#549.

Fixes issues: #55

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#549.

Fixes issues: #55


PoolExchange storage exchange = exchanges[exchangeId];
exchange.exitContribution = exitContribution;
Expand Down Expand Up @@ -290,6 +338,37 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
exchanges[exchangeId].tokenSupply = exchange.tokenSupply;
}

/**
* @notice Accounting of exit contribution on a swap.
* @dev Accounting of exit contribution without changing the current price of an exchange.
* this is done by updating the reserve ratio and subtracting the exit contribution from the token supply.
* Formula: newRatio = (Supply * oldRatio) / (Supply - exitContribution)
* @param exchangeId The ID of the pool
* @param exitContribution The amount of the token to be removed from the pool, scaled to 18 decimals
*/
function _accountExitContribution(bytes32 exchangeId, uint256 exitContribution) internal {
PoolExchange memory exchange = getPoolExchange(exchangeId);
uint256 scaledReserveRatio = uint256(exchange.reserveRatio) * 1e10;
UD60x18 nominator = wrap(exchange.tokenSupply).mul(wrap(scaledReserveRatio));
UD60x18 denominator = wrap(exchange.tokenSupply - exitContribution);
UD60x18 newRatioScaled = nominator.div(denominator);

uint256 newRatio = unwrap(newRatioScaled) / 1e10;

exchanges[exchangeId].reserveRatio = uint32(newRatio);
exchanges[exchangeId].tokenSupply -= exitContribution;
}

Comment on lines +341 to +361
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

Comment on lines +341 to +361
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#557.

Fixes issues: #36, #64

/**
* @notice Division and rounding up if there is a remainder
* @param a The dividend
* @param b The divisor
* @return The result of the division rounded up
*/
function divAndRoundUp(uint256 a, uint256 b) internal pure returns (uint256) {
return (a / b) + (a % b > 0 ? 1 : 0);
}

/**
* @notice Calculate the scaledAmountIn of tokenIn for a given scaledAmountOut of tokenOut
* @param exchange The pool exchange to operate on
Expand All @@ -307,8 +386,6 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
if (tokenIn == exchange.reserveAsset) {
scaledAmountIn = fundCost(exchange.tokenSupply, exchange.reserveBalance, exchange.reserveRatio, scaledAmountOut);
} else {
// apply exit contribution
scaledAmountOut = (scaledAmountOut * MAX_WEIGHT) / (MAX_WEIGHT - exchange.exitContribution);
scaledAmountIn = saleCost(exchange.tokenSupply, exchange.reserveBalance, exchange.reserveRatio, scaledAmountOut);
}
}
Expand Down Expand Up @@ -341,8 +418,6 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
exchange.reserveRatio,
scaledAmountIn
);
// apply exit contribution
scaledAmountOut = (scaledAmountOut * (MAX_WEIGHT - exchange.exitContribution)) / MAX_WEIGHT;
}
}

Expand All @@ -362,6 +437,7 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B
require(exchange.reserveRatio > 1, "Reserve ratio is too low");
require(exchange.reserveRatio <= MAX_WEIGHT, "Reserve ratio is too high");
require(exchange.exitContribution <= MAX_WEIGHT, "Exit contribution is too high");
require(exchange.reserveBalance > 0, "Reserve balance must be greater than 0");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#558.

Fixes issues: #57

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#558.

Fixes issues: #57

}

/**
Expand Down
40 changes: 27 additions & 13 deletions mento-core/contracts/goodDollar/GoodDollarExchangeProvider.sol
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,12 @@ contract GoodDollarExchangeProvider is IGoodDollarExchangeProvider, BancorExchan
PoolExchange memory exchange = getPoolExchange(exchangeId);

UD60x18 scaledRatio = wrap(uint256(exchange.reserveRatio) * 1e10);
UD60x18 newRatio = scaledRatio.mul(wrap(reserveRatioScalar));

// The division and multiplication by 1e10 here ensures that the new ratio used for calculating the amount to mint
// is the same as the one set in the exchange but only scaled to 18 decimals.
// Ignored, because the division and multiplication by 1e10 is needed see comment above.
// slither-disable-next-line divide-before-multiply
UD60x18 newRatio = wrap((unwrap(scaledRatio.mul(wrap(reserveRatioScalar))) / 1e10) * 1e10);
Comment on lines +147 to +152
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#548.

Fixes issues: #21

Comment on lines +147 to +152
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#548.

Fixes issues: #21


uint32 newRatioUint = uint32(unwrap(newRatio) / 1e10);
require(newRatioUint > 0, "New ratio must be greater than 0");
Expand Down Expand Up @@ -175,36 +180,45 @@ contract GoodDollarExchangeProvider is IGoodDollarExchangeProvider, BancorExchan
) external onlyExpansionController whenNotPaused returns (uint256 amountToMint) {
PoolExchange memory exchange = getPoolExchange(exchangeId);

uint256 reserveinterestScaled = reserveInterest * tokenPrecisionMultipliers[exchange.reserveAsset];
uint256 amountToMintScaled = unwrap(
wrap(reserveinterestScaled).mul(wrap(exchange.tokenSupply)).div(wrap(exchange.reserveBalance))
wrap(reserveInterest).mul(wrap(exchange.tokenSupply)).div(wrap(exchange.reserveBalance))
);
amountToMint = amountToMintScaled / tokenPrecisionMultipliers[exchange.tokenAddress];

exchanges[exchangeId].tokenSupply += amountToMintScaled;
exchanges[exchangeId].reserveBalance += reserveinterestScaled;
exchanges[exchangeId].reserveBalance += reserveInterest;

return amountToMint;
}

/**
* @inheritdoc IGoodDollarExchangeProvider
* @dev Calculates the new reserve ratio needed to mint the G$ reward while keeping the current price the same.
* calculation: newRatio = reserveBalance / (tokenSupply + reward) * currentPrice
* calculation: newRatio = (tokenSupply * reserveRatio) / (tokenSupply + reward)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

*/
function updateRatioForReward(bytes32 exchangeId, uint256 reward) external onlyExpansionController whenNotPaused {
function updateRatioForReward(
bytes32 exchangeId,
uint256 reward,
uint256 maxSlippagePercentage
) external onlyExpansionController whenNotPaused {
Comment on lines +199 to +203
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

Comment on lines +199 to +203
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

PoolExchange memory exchange = getPoolExchange(exchangeId);

uint256 currentPriceScaled = currentPrice(exchangeId) * tokenPrecisionMultipliers[exchange.reserveAsset];
uint256 rewardScaled = reward * tokenPrecisionMultipliers[exchange.tokenAddress];
uint256 scaledRatio = uint256(exchange.reserveRatio) * 1e10;
uint256 scaledReward = reward * tokenPrecisionMultipliers[exchange.tokenAddress];

UD60x18 numerator = wrap(exchange.tokenSupply).mul(wrap(scaledRatio));
UD60x18 denominator = wrap(exchange.tokenSupply).add(wrap(scaledReward));
uint256 newScaledRatio = unwrap(numerator.div(denominator));
Comment on lines +206 to +211
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

Comment on lines +206 to +211
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59


uint32 newRatioUint = uint32(newScaledRatio / 1e10);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59


require(newRatioUint > 0, "New ratio must be greater than 0");

Comment on lines +215 to 216
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#544.

Fixes issues: #29

Comment on lines +215 to 216
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#544.

Fixes issues: #29

UD60x18 numerator = wrap(exchange.reserveBalance);
UD60x18 denominator = wrap(exchange.tokenSupply + rewardScaled).mul(wrap(currentPriceScaled));
uint256 newRatioScaled = unwrap(numerator.div(denominator));
uint256 allowedSlippage = (exchange.reserveRatio * maxSlippagePercentage) / MAX_WEIGHT;
require(exchange.reserveRatio - newRatioUint <= allowedSlippage, "Slippage exceeded");

Comment on lines +217 to 219
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

Comment on lines +217 to 219
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

uint32 newRatioUint = uint32(newRatioScaled / 1e10);
exchanges[exchangeId].reserveRatio = newRatioUint;
exchanges[exchangeId].tokenSupply += rewardScaled;
exchanges[exchangeId].tokenSupply += scaledReward;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change related to mento-protocol/mento-core#554.

Fixes issues: #59


emit ReserveRatioUpdated(exchangeId, newRatioUint);
}
Expand Down
Loading