-
Notifications
You must be signed in to change notification settings - Fork 0
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
base: main
Are you sure you want to change the base?
Fix Review #2
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. |
||
uint256 scaledAmountOut = _getScaledAmountOut(exchange, tokenIn, tokenOut, scaledAmountIn); | ||
amountOut = scaledAmountOut / tokenPrecisionMultipliers[tokenOut]; | ||
return amountOut; | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557.
Comment on lines
+147
to
+153
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. |
||
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; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#560. Fixes issues: #23 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#560. Fixes issues: #23 |
||
} | ||
|
||
/* ============================================================ */ | ||
|
@@ -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"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#545. Fixes issues: #79 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#545. Fixes issues: #79 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557.
Comment on lines
+215
to
+223
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. |
||
uint256 scaledAmountOut = _getScaledAmountOut(exchange, tokenIn, tokenOut, scaledAmountIn); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. |
||
executeSwap(exchangeId, tokenIn, scaledAmountIn, scaledAmountOut); | ||
if (exitContribution > 0) { | ||
_accountExitContribution(exchangeId, exitContribution); | ||
} | ||
Comment on lines
+227
to
+229
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557.
Comment on lines
+227
to
+229
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. |
||
|
||
amountOut = scaledAmountOut / tokenPrecisionMultipliers[tokenOut]; | ||
return amountOut; | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557.
Comment on lines
+245
to
+258
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. |
||
executeSwap(exchangeId, tokenIn, scaledAmountIn, scaledAmountOut); | ||
if (exitContribution > 0) { | ||
_accountExitContribution(exchangeId, exitContribution); | ||
} | ||
Comment on lines
+260
to
+262
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557.
Comment on lines
+260
to
+262
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. |
||
|
||
amountIn = scaledAmountIn / tokenPrecisionMultipliers[tokenIn]; | ||
amountIn = divAndRoundUp(scaledAmountInWithExitContribution, tokenPrecisionMultipliers[tokenIn]); | ||
return amountIn; | ||
} | ||
|
||
|
@@ -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); | ||
|
@@ -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"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#549. Fixes issues: #55 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557.
Comment on lines
+341
to
+361
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#557. |
||
/** | ||
* @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 | ||
|
@@ -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); | ||
} | ||
} | ||
|
@@ -341,8 +418,6 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B | |
exchange.reserveRatio, | ||
scaledAmountIn | ||
); | ||
// apply exit contribution | ||
scaledAmountOut = (scaledAmountOut * (MAX_WEIGHT - exchange.exitContribution)) / MAX_WEIGHT; | ||
} | ||
} | ||
|
||
|
@@ -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"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#558. Fixes issues: #57 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change related to mento-protocol/mento-core#558. Fixes issues: #57 |
||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
diff a/mento-core/contracts/goodDollar/BancorExchangeProvider.sol b/mento-core/contracts/goodDollar/BancorExchangeProvider.sol (rejected hunks) | ||
@@ -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; | ||
+ } | ||
+ | ||
uint256 scaledAmountOut = _getScaledAmountOut(exchange, tokenIn, tokenOut, scaledAmountIn); | ||
amountOut = scaledAmountOut / tokenPrecisionMultipliers[tokenOut]; | ||
return amountOut; | ||
@@ -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"); | ||
+ } | ||
+ | ||
+ 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; | ||
+ | ||
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]; | ||
} | ||
|
||
/* ============================================================ */ | ||
@@ -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"); | ||
reserve = IReserve(_reserve); | ||
- emit ReserveUpdated(address(_reserve)); | ||
+ emit ReserveUpdated(_reserve); | ||
} | ||
|
||
/// @inheritdoc IBancorExchangeProvider | ||
@@ -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; | ||
+ } | ||
+ | ||
uint256 scaledAmountOut = _getScaledAmountOut(exchange, tokenIn, tokenOut, scaledAmountIn); | ||
+ | ||
executeSwap(exchangeId, tokenIn, scaledAmountIn, scaledAmountOut); | ||
+ if (exitContribution > 0) { | ||
+ _accountExitContribution(exchangeId, exitContribution); | ||
+ } | ||
|
||
amountOut = scaledAmountOut / tokenPrecisionMultipliers[tokenOut]; | ||
return amountOut; | ||
@@ -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; | ||
+ } | ||
+ | ||
executeSwap(exchangeId, tokenIn, scaledAmountIn, scaledAmountOut); | ||
+ if (exitContribution > 0) { | ||
+ _accountExitContribution(exchangeId, exitContribution); | ||
+ } | ||
|
||
- amountIn = scaledAmountIn / tokenPrecisionMultipliers[tokenIn]; | ||
+ amountIn = divAndRoundUp(scaledAmountInWithExitContribution, tokenPrecisionMultipliers[tokenIn]); | ||
return amountIn; | ||
} | ||
|
||
@@ -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); | ||
@@ -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"); | ||
|
||
PoolExchange storage exchange = exchanges[exchangeId]; | ||
exchange.exitContribution = exitContribution; | ||
@@ -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; | ||
+ } | ||
+ | ||
+ /** | ||
+ * @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 | ||
@@ -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); | ||
} | ||
} | ||
@@ -341,8 +418,6 @@ contract BancorExchangeProvider is IExchangeProvider, IBancorExchangeProvider, B | ||
exchange.reserveRatio, | ||
scaledAmountIn | ||
); | ||
- // apply exit contribution | ||
- scaledAmountOut = (scaledAmountOut * (MAX_WEIGHT - exchange.exitContribution)) / MAX_WEIGHT; | ||
} | ||
} | ||
|
||
@@ -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"); | ||
} | ||
|
||
/** |
There was a problem hiding this comment.
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