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

Fuzz fix rebalance issue #1095

Merged
merged 3 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 0 additions & 1 deletion contracts/fuzz/CollateralMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ contract CollateralMock is OracleErrorMock, AppreciatingFiatCollateral {
function underlyingRefPerTok() public view virtual override returns (uint192) {
return refPerTokModel.price();
}

}

// A CollateralMock that does not use decaying lotPrice()s, but instead just returns the last saved
Expand Down
16 changes: 13 additions & 3 deletions contracts/fuzz/FuzzP1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ contract BasketHandlerP1Fuzz is BasketHandlerP1 {
return IMainFuzz(address(main)).translateAddr(msg.sender);
}

function basketLength() public view returns (uint256) {
return basket.erc20s.length;
}

function savePrev() external {
prev.setFrom(basket);
}
Expand Down Expand Up @@ -194,10 +198,16 @@ contract BackingManagerP1Fuzz is BackingManagerP1 {
}

function isBasketRangeSmaller() external view returns (bool) {
BasketHandlerP1Fuzz bh = BasketHandlerP1Fuzz(
address(IMainFuzz(address(main)).basketHandler())
);
BasketRange memory currentRange = getCurrentBasketRange();

return
currentRange.top <= basketRangePrev.top &&
currentRange.bottom >= basketRangePrev.bottom;
currentRange.top <=
basketRangePrev.top.mul(FIX_ONE.plus(maxTradeSlippage), CEIL) + bh.basketLength() &&
currentRange.bottom >=
basketRangePrev.bottom.mul(FIX_ONE.minus(maxTradeSlippage), FLOOR);
}

function isValidSurplusToken(IERC20 token) external view returns (bool) {
Expand Down Expand Up @@ -339,7 +349,7 @@ contract BrokerP1Fuzz is BrokerP1 {

trade.init(caller, req.sell, req.buy, req.sellAmount, dutchAuctionLength, prices);
tradeSet.add(address(trade));
tradeKindSet[address(trade)] = uint256(TradeKind.BATCH_AUCTION);
tradeKindSet[address(trade)] = uint256(TradeKind.DUTCH_AUCTION);
lastOpenedTrade = trade;
return trade;
}
Expand Down
6 changes: 3 additions & 3 deletions contracts/fuzz/scenarios/ChaosOps.sol
Original file line number Diff line number Diff line change
Expand Up @@ -730,13 +730,13 @@ contract ChaosOpsScenario {

function setPrimeBasket() public {
BasketHandlerP1Fuzz bh = BasketHandlerP1Fuzz(address(main.basketHandler()));
// if(!bh.reweightable()) _validateWeights();
// if(!bh.reweightable()) _validateWeights();
bh.setPrimeBasket(backingForPrimeBasket, targetAmtsForPrimeBasket);
}

function forceSetPrimeBasket() public {
function forceSetPrimeBasket() public {
BasketHandlerP1Fuzz bh = BasketHandlerP1Fuzz(address(main.basketHandler()));
// if(!bh.reweightable()) _validateWeights();
// if(!bh.reweightable()) _validateWeights();
bh.forceSetPrimeBasket(backingForPrimeBasket, targetAmtsForPrimeBasket);
}

Expand Down
155 changes: 104 additions & 51 deletions contracts/fuzz/scenarios/Rebalancing.sol
Original file line number Diff line number Diff line change
Expand Up @@ -250,22 +250,39 @@ contract RebalancingScenario {
// ================ mutators ================

// ==== user functions: token ops ====
function transfer(uint8 userID, uint8 tokenID, uint256 amount) public asSender {
function transfer(
uint8 userID,
uint8 tokenID,
uint256 amount
) public asSender {
IERC20Metadata token = IERC20Metadata(address(main.someToken(tokenID)));
token.transfer(main.someAddr(userID), amount);
}

function approve(uint8 spenderID, uint8 tokenID, uint256 amount) public asSender {
function approve(
uint8 spenderID,
uint8 tokenID,
uint256 amount
) public asSender {
IERC20 token = main.someToken(tokenID);
token.approve(main.someAddr(spenderID), amount);
}

function transferFrom(uint8 fromID, uint8 toID, uint8 tokenID, uint256 amount) public asSender {
function transferFrom(
uint8 fromID,
uint8 toID,
uint8 tokenID,
uint256 amount
) public asSender {
IERC20 token = main.someToken(tokenID);
token.transferFrom(main.someAddr(fromID), main.someAddr(toID), amount);
}

function mint(uint8 userID, uint8 tokenID, uint256 amount) public {
function mint(
uint8 userID,
uint8 tokenID,
uint256 amount
) public {
IERC20Metadata token = IERC20Metadata(address(main.someToken(tokenID)));
require(
address(token) != address(main.rToken()) && address(token) != address(main.stRSR()),
Expand All @@ -275,7 +292,11 @@ contract RebalancingScenario {
require(token.totalSupply() <= 1e57, "Do not mint 'unreasonably' many tokens");
}

function burn(uint8 userID, uint8 tokenID, uint256 amount) public {
function burn(
uint8 userID,
uint8 tokenID,
uint256 amount
) public {
IERC20 token = main.someToken(tokenID);
require(
address(token) != address(main.rToken()) && address(token) != address(main.stRSR()),
Expand Down Expand Up @@ -358,9 +379,10 @@ contract RebalancingScenario {
}

// unregisterAsset: Only BEFORE Rebalancing
function unregisterAsset(
uint8 tokenID
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) {
function unregisterAsset(uint8 tokenID)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
{
IERC20 erc20 = main.someToken(tokenID);
IAssetRegistry reg = main.assetRegistry();
require(reg.isRegistered(erc20), "erc20 not registered");
Expand Down Expand Up @@ -393,28 +415,33 @@ contract RebalancingScenario {
}

// do issuance without doing allowances first
function justIssue(
uint256 amount
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) asSender {
function justIssue(uint256 amount)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
asSender
{
_saveRTokenRate();
main.rToken().issue(amount);
}

// do issuance without doing allowances first
function justIssueTo(
uint256 amount,
uint8 recipientID
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) asSender {
function justIssueTo(uint256 amount, uint8 recipientID)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
asSender
{
_saveRTokenRate();
address recipient = main.someAddr(recipientID);

main.rToken().issueTo(recipient, amount);
}

// do allowances as needed, and *then* do issuance
function issue(
uint256 amount
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) asSender {
function issue(uint256 amount)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
asSender
{
_saveRTokenRate();
uint256 preSupply = main.rToken().totalSupply();
require(amount + preSupply <= 1e48, "Do not issue 'unreasonably' many rTokens");
Expand All @@ -429,10 +456,11 @@ contract RebalancingScenario {
}

// do allowances as needed, and *then* do issuance
function issueTo(
uint256 amount,
uint8 recipientID
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) asSender {
function issueTo(uint256 amount, uint8 recipientID)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
asSender
{
_saveRTokenRate();
address recipient = main.someAddr(recipientID);
uint256 preSupply = main.rToken().totalSupply();
Expand All @@ -447,17 +475,20 @@ contract RebalancingScenario {
main.rToken().issueTo(recipient, amount);
}

function redeem(
uint256 amount
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) asSender {
function redeem(uint256 amount)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
asSender
{
_saveRTokenRate();
main.rToken().redeem(amount);
}

function redeemTo(
uint256 amount,
uint8 recipientID
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) asSender {
function redeemTo(uint256 amount, uint8 recipientID)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
asSender
{
_saveRTokenRate();
address recipient = main.someAddr(recipientID);
main.rToken().redeemTo(recipient, amount);
Expand All @@ -484,8 +515,8 @@ contract RebalancingScenario {
}

(address[] memory erc20sOut, uint256[] memory amountsOut) = main
.basketHandler()
.quoteCustomRedemption(redeemableBasketNonces, portions, amount);
.basketHandler()
.quoteCustomRedemption(redeemableBasketNonces, portions, amount);

main.rToken().redeemCustom(
recipient,
Expand Down Expand Up @@ -545,7 +576,13 @@ contract RebalancingScenario {

// ==== keeper functions ====
// swapRegisterAsset: Only impact refPerTok() and targetPerRef() BEFORE Rebalancing
function updatePrice(uint256 seedID, uint192 a, uint192 b, uint192 c, uint192 d) public {
function updatePrice(
uint256 seedID,
uint192 a,
uint192 b,
uint192 c,
uint192 d
) public {
IERC20 erc20 = main.someToken(seedID);
IAssetRegistry reg = main.assetRegistry();
if (!reg.isRegistered(erc20)) return;
Expand Down Expand Up @@ -633,7 +670,11 @@ contract RebalancingScenario {
}

// do revenue distribution without doing allowances first
function justDistributeRevenue(uint256 tokenID, uint8 fromID, uint256 amount) public asSender {
function justDistributeRevenue(
uint256 tokenID,
uint8 fromID,
uint256 amount
) public asSender {
IERC20 token = main.someToken(tokenID);
// distribute now uses msg.sender (2/1/23), so spoof from caller
address fromUser = main.someAddr(fromID);
Expand All @@ -643,7 +684,11 @@ contract RebalancingScenario {
}

// do revenue distribution granting allowance first - only RSR or RToken
function distributeRevenue(uint8 which, uint8 fromID, uint256 amount) public {
function distributeRevenue(
uint8 which,
uint8 fromID,
uint256 amount
) public {
IERC20 token;

which %= 2;
Expand Down Expand Up @@ -713,10 +758,10 @@ contract RebalancingScenario {
IERC20[] internal backingForPrimeBasket;
uint192[] internal targetAmtsForPrimeBasket;

function pushBackingForPrimeBasket(
uint256 tokenID,
uint256 seed
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) {
function pushBackingForPrimeBasket(uint256 tokenID, uint256 seed)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
{
backingForPrimeBasket.push(main.someToken(tokenID));
targetAmtsForPrimeBasket.push(uint192(between(1, 1000e18, seed)));
// 1000e18 is BH.MAX_TARGET_AMT
Expand Down Expand Up @@ -769,9 +814,10 @@ contract RebalancingScenario {
// Backup basket
mapping(bytes32 => IERC20[]) internal backingForBackup;

function pushBackingForBackup(
uint256 tokenID
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) {
function pushBackingForBackup(uint256 tokenID)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
{
IERC20 token = main.someToken(tokenID);
IAssetRegistry reg = main.assetRegistry();
if (!reg.isRegistered(token)) return;
Expand All @@ -783,16 +829,18 @@ contract RebalancingScenario {
}
}

function popBackingForBackup(
uint8 targetNameID
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) {
function popBackingForBackup(uint8 targetNameID)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
{
bytes32 targetName = someTargetName(targetNameID);
if (backingForBackup[targetName].length > 0) backingForBackup[targetName].pop();
}

function setBackupConfig(
uint8 targetNameID
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) {
function setBackupConfig(uint8 targetNameID)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
{
BasketHandlerP1Fuzz bh = BasketHandlerP1Fuzz(address(main.basketHandler()));
bytes32 targetName = someTargetName(targetNameID);
bh.setBackupConfig(
Expand Down Expand Up @@ -849,7 +897,11 @@ contract RebalancingScenario {
TestIRToken(address(main.rToken())).setRedemptionThrottleParams(params);
}

function setDistribution(uint256 seedID, uint16 rTokenDist, uint16 rsrDist) public {
function setDistribution(
uint256 seedID,
uint16 rTokenDist,
uint16 rsrDist
) public {
RevenueShare memory dist = RevenueShare(rTokenDist, rsrDist);
main.distributor().setDistribution(main.someAddr(seedID), dist);
}
Expand Down Expand Up @@ -973,9 +1025,10 @@ contract RebalancingScenario {
);
}

function setReweightable(
uint256 seed
) public onlyDuringState(ScenarioStatus.BEFORE_REBALANCING) {
function setReweightable(uint256 seed)
public
onlyDuringState(ScenarioStatus.BEFORE_REBALANCING)
{
BasketHandlerP1Fuzz bh = BasketHandlerP1Fuzz(address(main.basketHandler()));
seed %= 2;
if (seed == 0) bh.setReweightable(false);
Expand Down
Loading
Loading