Skip to content

Commit

Permalink
Redemption fixes and testing (mstable#47)
Browse files Browse the repository at this point in the history
* Fixed redemption and implemented basic tests

* Resolved JamesLint changes
  • Loading branch information
superduck35 authored Mar 18, 2020
1 parent a97742b commit 1583221
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 394 deletions.
102 changes: 52 additions & 50 deletions contracts/masset/Masset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -373,56 +373,57 @@ contract Masset is IMasset, MassetToken, PausableModule {
internal
returns (uint256 massetRedeemed)
{
// require(_recipient != address(0), "Recipient must not be 0x0");
// uint256 redemptionAssetCount = _bassetQuantities.length;

// // Fetch high level details
// Basket memory basket = basketManager.getBasket();

// // Load only needed bAssets in array
// (Basset[] memory bAssets, address[] memory integrators, uint8[] memory indexes)
// = basketManager.getForgeBassets(_bassetsBitmap, uint8(redemptionAssetCount), false);

// // Validate redemption
// (bool isValid, string memory reason) =
// forgeValidator.validateRedemption(basket.bassets, basket.failed, totalSupply(), indexes, _bassetQuantities);
// require(isValid, reason);

// uint256 massetQuantity = 0;

// // Calc MassetQ and update the Vault
// for(uint256 i = 0; i < redemptionAssetCount; i++){
// if(_bassetQuantities[i] > 0){
// // Calc equivalent mAsset amount
// uint256 ratioedBasset = _bassetQuantities[i].mulRatioTruncateCeil(bAssets[i].ratio);
// massetQuantity = massetQuantity.add(ratioedBasset);

// // bAsset == bAssets[i] == basket.bassets[indexes[i]]
// basketManager.decreaseVaultBalance(indexes[i], integrators[i], _bassetQuantities[i]);
// }
// }

// // Pay the redemption fee
// _payRedemptionFee(massetQuantity, msg.sender);

// // Ensure payout is relevant to collateralisation ratio (if ratio is 90%, we burn more)
// massetQuantity = massetQuantity.divPrecisely(basket.collateralisationRatio);

// // Burn the Masset
// _burn(msg.sender, massetQuantity);

// // Transfer the Bassets to the user
// for(uint256 i = 0; i < redemptionAssetCount; i++){
// if(_bassetQuantities[i] > 0){
// IPlatformIntegration(integrators[i]).withdraw(_recipient, bAssets[i].addr, _bassetQuantities[i]);
// }
// }

// emit RedeemedMulti(_recipient, msg.sender, massetQuantity, _bassetsBitmap, _bassetQuantities);
// return massetQuantity;
return 0;
require(_recipient != address(0), "Recipient must not be 0x0");
uint256 redemptionAssetCount = _bassetQuantities.length;

// Fetch high level details
Basket memory basket = basketManager.getBasket();

// Load only needed bAssets in array
(Basset[] memory bAssets, address[] memory integrators, uint8[] memory indexes)
= basketManager.getForgeBassets(_bassetsBitmap, uint8(redemptionAssetCount), false);

// Validate redemption
(bool isValid, string memory reason) =
forgeValidator.validateRedemption(basket.bassets, basket.failed, totalSupply(), indexes, _bassetQuantities);
require(isValid, reason);

uint256 massetQuantity = 0;

// Calc MassetQ and update the Vault
for(uint256 i = 0; i < redemptionAssetCount; i++){
uint256 bAssetQuantity = _bassetQuantities[i];
if(bAssetQuantity > 0){
// Calc equivalent mAsset amount
uint256 ratioedBasset = bAssetQuantity.mulRatioTruncateCeil(bAssets[i].ratio);
massetQuantity = massetQuantity.add(ratioedBasset);

// bAsset == bAssets[i] == basket.bassets[indexes[i]]
basketManager.decreaseVaultBalance(indexes[i], integrators[i], bAssetQuantity);
}
}

// Pay the redemption fee
_payRedemptionFee(massetQuantity, msg.sender);

// Ensure payout is relevant to collateralisation ratio (if ratio is 90%, we burn more)
massetQuantity = massetQuantity.divPrecisely(basket.collateralisationRatio);

// Burn the Masset
_burn(msg.sender, massetQuantity);

// Transfer the Bassets to the user
for(uint256 i = 0; i < redemptionAssetCount; i++){
if(_bassetQuantities[i] > 0){
IPlatformIntegration(integrators[i]).withdraw(_recipient, bAssets[i].addr, _bassetQuantities[i]);
}
}

emit RedeemedMulti(_recipient, msg.sender, massetQuantity, _bassetsBitmap, _bassetQuantities);
return massetQuantity;
}


/**
* @dev Pay the forging fee by burning MetaToken
* @param _quantity Exact amount of Masset being forged
Expand All @@ -435,9 +436,10 @@ contract Masset is IMasset, MassetToken, PausableModule {
if(feeRate > 0){
// e.g. for 500 massets.
// feeRate == 1% == 1e16. _quantity == 5e20.
uint256 amountOfMassetSubjectToFee = feeRate.mulTruncate(_quantity);
// (5e20 * 1e16) / 1e18 = 5e18
uint256 amountOfMassetSubjectToFee = _quantity.mulTruncate(feeRate);

require(transferFrom(_payer, feeRecipient, amountOfMassetSubjectToFee), "Must be successful fee payment");
_transfer(_payer, feeRecipient, amountOfMassetSubjectToFee);

emit PaidFee(_payer, amountOfMassetSubjectToFee, feeRate);
}
Expand Down
4 changes: 2 additions & 2 deletions contracts/masset/forge-validator/ForgeValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ contract ForgeValidator is IForgeValidator {
}

response.ratioedBassetVaults[i] = _bassets[i].vaultBalance.mulRatioTruncate(_bassets[i].ratio);
uint256 maxWeightInUnits = _bassets[i].maxWeight.mulTruncate(_total);
uint256 maxWeightInUnits = _total.mulTruncate(_bassets[i].maxWeight);

// If the bAsset is de-pegged on the up-side, it doesn't matter if it goes above max
bool bassetOverWeight = response.ratioedBassetVaults[i] > maxWeightInUnits && status != BassetStatus.BrokenAbovePeg;
Expand All @@ -239,7 +239,7 @@ contract ForgeValidator is IForgeValidator {
atLeastOneOverweight = false;

for(uint256 i = 0; i < len; i++) {
uint256 maxWeightInUnits = _bAssets[i].maxWeight.mulTruncate(_newTotal);
uint256 maxWeightInUnits = _newTotal.mulTruncate(_bAssets[i].maxWeight);
// If the bAsset is de-pegged on the up-side, it doesn't matter if it goes above max
bool bassetOverWeight = _ratioedBassetVaultsAfter[i] > maxWeightInUnits && _bAssets[i].status != BassetStatus.BrokenAbovePeg;

Expand Down
Loading

0 comments on commit 1583221

Please sign in to comment.