From e46b26cadaf970ef29cb03b0f9309872400628ce Mon Sep 17 00:00:00 2001 From: Mae Date: Wed, 25 Jan 2023 11:31:48 -0800 Subject: [PATCH] fix:broken tests --- .../contracts/src/dollar/ERC20Ubiquity.sol | 26 +- packages/contracts/src/dollar/Staking.sol | 248 +++++++++++------- .../contracts/src/dollar/StakingShare.sol | 5 +- .../contracts/src/dollar/UbiquityChef.sol | 158 ++++++----- .../contracts/src/dollar/UbiquityFormulas.sol | 41 +-- .../contracts/src/dollar/core/CreditClock.sol | 2 +- .../contracts/src/dollar/core/CreditNFT.sol | 9 +- .../src/dollar/core/DollarMintExcess.sol | 43 ++- .../src/dollar/core/TWAPOracleDollar3pool.sol | 25 +- .../src/dollar/mocks/MockBondingV1.sol | 10 +- .../test/dollar/core/CreditClock.t.sol | 3 +- .../test/dollar/core/CreditNFT.t.sol | 6 +- .../test/dollar/core/DollarMintExcess.t.sol | 29 +- .../test/helpers/LocalTestHelper.sol | 5 +- 14 files changed, 355 insertions(+), 255 deletions(-) diff --git a/packages/contracts/src/dollar/ERC20Ubiquity.sol b/packages/contracts/src/dollar/ERC20Ubiquity.sol index 2ec8fec0a..4000d51e5 100644 --- a/packages/contracts/src/dollar/ERC20Ubiquity.sol +++ b/packages/contracts/src/dollar/ERC20Ubiquity.sol @@ -59,9 +59,11 @@ contract ERC20Ubiquity is IERC20Ubiquity, ERC20, ERC20Burnable, ERC20Pausable { _; } - constructor(address _manager, string memory name_, string memory symbol_) - ERC20(name_, symbol_) - { + constructor( + UbiquityDollarManager _manager, + string memory name_, + string memory symbol_ + ) ERC20(name_, symbol_) { _tokenName = name_; _symbol = symbol_; manager = _manager; @@ -147,11 +149,9 @@ contract ERC20Ubiquity is IERC20Ubiquity, ERC20, ERC20Burnable, ERC20Pausable { /// @notice burn Ubiquity Dollar tokens from caller /// @param amount the amount to burn - function burn(uint256 amount) - public - override (ERC20Burnable, IERC20Ubiquity) - whenNotPaused - { + function burn( + uint256 amount + ) public override(ERC20Burnable, IERC20Ubiquity) whenNotPaused { super.burn(amount); emit Burning(msg.sender, amount); } @@ -173,12 +173,10 @@ contract ERC20Ubiquity is IERC20Ubiquity, ERC20, ERC20Burnable, ERC20Pausable { } // @dev Creates `amount` new tokens for `to`. - function mint(address to, uint256 amount) - public - override - onlyMinter - whenNotPaused - { + function mint( + address to, + uint256 amount + ) public override onlyMinter whenNotPaused { _mint(to, amount); emit Minting(to, msg.sender, amount); } diff --git a/packages/contracts/src/dollar/Staking.sol b/packages/contracts/src/dollar/Staking.sol index d0a400a15..868e63dc2 100644 --- a/packages/contracts/src/dollar/Staking.sol +++ b/packages/contracts/src/dollar/Staking.sol @@ -207,10 +207,12 @@ contract Staking is IStaking, CollectableDust, Pausable { ); // update twap ITWAPOracleDollar3pool(manager.twapOracleAddress()).update(); - uint256 toTransfer = - IERC20(manager.curve3PoolTokenAddress()).balanceOf(address(this)); + uint256 toTransfer = IERC20(manager.curve3PoolTokenAddress()).balanceOf( + address(this) + ); IERC20(manager.curve3PoolTokenAddress()).transfer( - manager.treasuryAddress(), toTransfer + manager.treasuryAddress(), + toTransfer ); emit PriceReset( manager.curve3PoolTokenAddress(), @@ -219,11 +221,10 @@ contract Staking is IStaking, CollectableDust, Pausable { ); } - function setStakingFormulasAddress(address _stakingFormulasAddress) - external - onlyStakingManager - { - stakingFormulasAddress = _stakingFormulasAddress; + function setStakingFormulas( + StakingFormulas _stakingFormulas + ) external onlyStakingManager { + stakingFormulas = _stakingFormulas; } /// Collectable Dust @@ -263,15 +264,14 @@ contract Staking is IStaking, CollectableDust, Pausable { /// @dev deposit uAD-3CRV LP tokens for a duration to receive staking shares /// @param _lpsAmount of LP token to send - /// @param lockup during lp token will be held - /// @notice weeks act as a multiplier for the amount of staking shares to be received - function deposit(uint256 _lpsAmount, uint256 _weeks) - external - whenNotPaused - returns (uint256 _id) - { + /// @param _lockup number of weeks during lp token will be held + /// @notice _lockup act as a multiplier for the amount of staking shares to be received + function deposit( + uint256 _lpsAmount, + uint256 _lockup + ) external whenNotPaused returns (uint256 _id) { require( - 1 <= lockup && lockup <= 208, + 1 <= _lockup && _lockup <= 208, "Staking: duration must be between 1 and 208 weeks" ); ITWAPOracleDollar3pool(manager.twapOracleAddress()).update(); @@ -280,14 +280,16 @@ contract Staking is IStaking, CollectableDust, Pausable { _updateLpPerShare(); // transfer lp token to the staking contract IERC20(manager.stableSwapMetaPoolAddress()).safeTransferFrom( - msg.sender, address(this), _lpsAmount + msg.sender, + address(this), + _lpsAmount ); // calculate the amount of share based on the amount of lp deposited and the duration uint256 _sharesAmount = IUbiquityFormulas(manager.formulasAddress()) - .durationMultiply(_lpsAmount, lockup, stakingDiscountMultiplier); + .durationMultiply(_lpsAmount, _lockup, stakingDiscountMultiplier); // calculate end locking period block number - uint256 _endBlock = block.number + lockup * blockCountInAWeek; + uint256 _endBlock = block.number + _lockup * blockCountInAWeek; _id = _mint(msg.sender, _lpsAmount, _sharesAmount, _endBlock); // set UbiquityChef for uGOV rewards @@ -298,73 +300,103 @@ contract Staking is IStaking, CollectableDust, Pausable { ); emit Deposit( - msg.sender, _id, _lpsAmount, _sharesAmount, _weeks, _endBlock - ); + msg.sender, + _id, + _lpsAmount, + _sharesAmount, + _lockup, + _endBlock + ); } /// @dev Add an amount of UbiquityDollar-3CRV LP tokens - /// @param amount of LP token to deposit - /// @param id staking shares id - /// @param lockup during lp token will be held + /// @param _amount of LP token to deposit + /// @param _id staking shares id + /// @param _lockup during lp token will be held /// @notice staking shares are ERC1155 (aka NFT) because they have an expiration date - function addLiquidity(uint256 _amount, uint256 _id, uint256 _weeks) - external - whenNotPaused - { - (uint256[2] memory bs, StakingShare.Stake memory stake) = - _checkForLiquidity(_id); + function addLiquidity( + uint256 _amount, + uint256 _id, + uint256 _lockup + ) external whenNotPaused { + ( + uint256[2] memory stakeInfo, + StakingShare.Stake memory stake + ) = _checkForLiquidity(_id); // calculate pending LP rewards uint256 sharesToRemove = stakeInfo[0]; _updateLpPerShare(); - uint256 pendingLpReward = - lpRewardForShares(sharesToRemove, stake.lpRewardDebt); + uint256 pendingLpReward = lpRewardForShares( + sharesToRemove, + stake.lpRewardDebt + ); // add an extra step to be able to decrease rewards if locking end is near - pendingLpReward = StakingFormulas(this.stakingFormulasAddress()) - .lpRewardsAddLiquidityNormalization(stake, bs, pendingLpReward); + pendingLpReward = stakingFormulas.lpRewardsAddLiquidityNormalization( + stake, + stakeInfo, + pendingLpReward + ); // add these LP Rewards to the deposited amount of LP token stake.lpAmount += pendingLpReward; lpRewards -= pendingLpReward; IERC20(manager.stableSwapMetaPoolAddress()).safeTransferFrom( - msg.sender, address(this), _amount + msg.sender, + address(this), + _amount ); stake.lpAmount += _amount; // redeem all shares IUbiquityChef(manager.masterChefAddress()).withdraw( - msg.sender, sharesToRemove, _id + msg.sender, + sharesToRemove, + _id ); // calculate the amount of share based on the new amount of lp deposited and the duration uint256 _sharesAmount = IUbiquityFormulas(manager.formulasAddress()) - .durationMultiply(stake.lpAmount, _weeks, stakingDiscountMultiplier); + .durationMultiply( + stake.lpAmount, + _lockup, + stakingDiscountMultiplier + ); // deposit new shares IUbiquityChef(manager.masterChefAddress()).deposit( - msg.sender, _sharesAmount, _id + msg.sender, + _sharesAmount, + _id ); // calculate end locking period block number // 1 week = 45361 blocks = 2371753*7/366 // n = (block + duration * 45361) - stake.endBlock = block.number + lockup * blockCountInAWeek; + stake.endBlock = block.number + _lockup * blockCountInAWeek; // calculate the amount of share based on the new amount of lp deposited and the duration - uint256 sharesAmount = - IUbiquityFormulas(manager.formulasAddress()).durationMultiply(amount, lockup, stakingDiscountMultiplier); - + uint256 sharesAmount = IUbiquityFormulas(manager.formulasAddress()) + .durationMultiply(_amount, _lockup, stakingDiscountMultiplier); + _updateLpPerShare(); - stake.lpRewardDebt = ( - IUbiquityChef(manager.masterChefAddress()).getStakingShareInfo(_id)[0] - * accLpRewardPerShare - ) / 1e12; + stake.lpRewardDebt = + (IUbiquityChef(manager.masterChefAddress()).getStakingShareInfo( + _id + )[0] * accLpRewardPerShare) / + 1e12; StakingShare(manager.stakingShareAddress()).updateStake( - _id, stake.lpAmount, stake.lpRewardDebt, stake.endBlock + _id, + stake.lpAmount, + stake.lpRewardDebt, + stake.endBlock ); emit AddLiquidityFromStake( - msg.sender, _id, stake.lpAmount, _sharesAmount - ); + msg.sender, + _id, + stake.lpAmount, + _sharesAmount + ); } /// @dev Remove an amount of uAD-3CRV LP tokens @@ -373,20 +405,29 @@ contract Staking is IStaking, CollectableDust, Pausable { /// @notice staking shares are ERC1155 (aka NFT) because they have an expiration date /// @param _id staking shares id /// @notice staking shares are ERC1155 (aka NFT) because they have an expiration date - function removeLiquidity(uint256 _amount, uint256 _id) - external - whenNotPaused - { - (uint256[2] memory bs, StakingShare.Stake memory stake) = - _checkForLiquidity(_id); + function removeLiquidity( + uint256 _amount, + uint256 _id + ) external whenNotPaused { + ( + uint256[2] memory stakeInfo, + StakingShare.Stake memory stake + ) = _checkForLiquidity(_id); require(stake.lpAmount >= _amount, "Staking: amount too big"); // we should decrease the UBQ rewards proportionally to the LP removed // sharesToRemove = (staking shares * _amount ) / stake.lpAmount ; - uint256 sharesToRemove = stakingFormulas.sharesForLP(stake, stakeInfo, _amount); + uint256 sharesToRemove = stakingFormulas.sharesForLP( + stake, + stakeInfo, + _amount + ); //get all its pending LP Rewards _updateLpPerShare(); - uint256 pendingLpReward = lpRewardForShares(stakeInfo[0], stake.lpRewardDebt); + uint256 pendingLpReward = lpRewardForShares( + stakeInfo[0], + stake.lpRewardDebt + ); lpRewards -= pendingLpReward; // update staking shares //stake.shares = stake.shares - sharesToRemove; @@ -404,27 +445,32 @@ contract Staking is IStaking, CollectableDust, Pausable { IERC20 metapool = IERC20(manager.stableSwapMetaPoolAddress()); // add an extra step to be able to decrease rewards if locking end is near - pendingLpReward = stakingFormulas.lpRewardsRemoveLiquidityNormalization(stake, stakeInfo, pendingLpReward); + pendingLpReward = stakingFormulas.lpRewardsRemoveLiquidityNormalization( + stake, + stakeInfo, + pendingLpReward + ); - uint256 correctedAmount = StakingFormulas(this.stakingFormulasAddress()) - .correctedAmountToWithdraw( + uint256 correctedAmount = stakingFormulas.correctedAmountToWithdraw( StakingShare(manager.stakingShareAddress()).totalLP(), metapool.balanceOf(address(this)) - lpRewards, _amount ); - - // stake.lpRewardDebt = (staking shares * accLpRewardPerShare) / 1e18; // user.amount.mul(pool.accSushiPerShare).div(1e12); // should be done after masterchef withdraw - stake.lpRewardDebt = ( - IUbiquityChef(manager.masterChefAddress()).getStakingShareInfo(_id)[0] - * accLpRewardPerShare - ) / 1e12; + stake.lpRewardDebt = + (IUbiquityChef(manager.masterChefAddress()).getStakingShareInfo( + _id + )[0] * accLpRewardPerShare) / + 1e12; StakingShare(manager.stakingShareAddress()).updateStake( - _id, stake.lpAmount, stake.lpRewardDebt, stake.endBlock + _id, + stake.lpAmount, + stake.lpRewardDebt, + stake.endBlock ); // lastly redeem lp tokens @@ -443,15 +489,15 @@ contract Staking is IStaking, CollectableDust, Pausable { function pendingLpRewards(uint256 _id) external view returns (uint256) { StakingShare staking = StakingShare(manager.stakingShareAddress()); StakingShare.Stake memory stake = staking.getStake(_id); - uint256[2] memory bs = - IUbiquityChef(manager.masterChefAddress()).getStakingShareInfo(_id); + uint256[2] memory stakeInfo = IUbiquityChef(manager.masterChefAddress()) + .getStakingShareInfo(_id); uint256 lpBalance = IERC20(manager.stableSwapMetaPoolAddress()) .balanceOf(address(this)); // the excess LP is the current balance minus the total deposited LP if (lpBalance >= (staking.totalLP() + totalLpToMigrate)) { - uint256 currentLpRewards = - lpBalance - (staking.totalLP() + totalLpToMigrate); + uint256 currentLpRewards = lpBalance - + (staking.totalLP() + totalLpToMigrate); uint256 curAccLpRewardPerShare = accLpRewardPerShare; // if new rewards we should calculate the new curAccLpRewardPerShare if (currentLpRewards > lpRewards) { @@ -464,8 +510,10 @@ contract Staking is IStaking, CollectableDust, Pausable { } // we multiply the shares amount by the accumulated lpRewards per share // and remove the lp Reward Debt - return (bs[0] * (curAccLpRewardPerShare)) / (1e12) - - (stake.lpRewardDebt); + return + (stakeInfo[0] * (curAccLpRewardPerShare)) / + (1e12) - + (stake.lpRewardDebt); } return 0; } @@ -519,14 +567,15 @@ contract Staking is IStaking, CollectableDust, Pausable { /// @dev migrate let a user migrate from V1 /// @notice user will then be able to migrate - function _migrate(address user, uint256 _lpsAmount, uint256 _weeks) - internal - returns (uint256 _id) - { + function _migrate( + address user, + uint256 _lpsAmount, + uint256 _lockup + ) internal returns (uint256 _id) { require(toMigrateId[user] > 0, "not v1 address"); require(_lpsAmount > 0, "LP amount is zero"); require( - 1 <= lockup && lockup <= 208, + 1 <= _lockup && _lockup <= 208, "Duration must be between 1 and 208 weeks" ); @@ -535,7 +584,7 @@ contract Staking is IStaking, CollectableDust, Pausable { // calculate the amount of share based on the amount of lp deposited and the duration uint256 _sharesAmount = IUbiquityFormulas(manager.formulasAddress()) - .durationMultiply(_lpsAmount, lockup, stakingDiscountMultiplier); + .durationMultiply(_lpsAmount, _lockup, stakingDiscountMultiplier); // update the accumulated lp rewards per shares _updateLpPerShare(); @@ -543,7 +592,7 @@ contract Staking is IStaking, CollectableDust, Pausable { // to keep the _updateLpPerShare calculation consistent totalLpToMigrate -= _lpsAmount; // calculate end locking period block number - uint256 endBlock = block.number + lockup * blockCountInAWeek; + uint256 endBlock = block.number + _lockup * blockCountInAWeek; _id = _mint(user, _lpsAmount, _sharesAmount, endBlock); // set UbiquityChef for uGOV rewards @@ -553,30 +602,31 @@ contract Staking is IStaking, CollectableDust, Pausable { _id ); - emit Migrated(user, _id, _lpsAmount, _sharesAmount, lockup); + emit Migrated(user, _id, _lpsAmount, _sharesAmount, _lockup); } /// @dev update the accumulated excess LP per share function _updateLpPerShare() internal { - StakingShare stake = StakingShare(manager.stakingShareAddress()); - uint256 lpBalance = - IERC20(manager.stableSwapMetaPoolAddress()).balanceOf(address(this)); + StakingShare stakingShare = StakingShare(manager.stakingShareAddress()); + uint256 lpBalance = IERC20(manager.stableSwapMetaPoolAddress()) + .balanceOf(address(this)); // the excess LP is the current balance // minus the total deposited LP + LP that needs to be migrated - uint256 totalShares = - IUbiquityChef(manager.masterChefAddress()).totalShares(); + uint256 totalShares = IUbiquityChef(manager.masterChefAddress()) + .totalShares(); if ( - lpBalance >= (stakingShare.totalLP() + totalLpToMigrate) - && totalShares > 0 + lpBalance >= (stakingShare.totalLP() + totalLpToMigrate) && + totalShares > 0 ) { - uint256 currentLpRewards = - lpBalance - (stake.totalLP() + totalLpToMigrate); + uint256 currentLpRewards = lpBalance - + (stakingShare.totalLP() + totalLpToMigrate); // is there new LP rewards to be distributed ? if (currentLpRewards > lpRewards) { // we calculate the new accumulated LP rewards per share - accLpRewardPerShare = accLpRewardPerShare - + (((currentLpRewards - lpRewards) * 1e12) / totalShares); + accLpRewardPerShare = + accLpRewardPerShare + + (((currentLpRewards - lpRewards) * 1e12) / totalShares); // update the staking contract lpRewards lpRewards = currentLpRewards; @@ -606,24 +656,28 @@ contract Staking is IStaking, CollectableDust, Pausable { ); } - function _checkForLiquidity(uint256 _id) + function _checkForLiquidity( + uint256 _id + ) internal - returns (uint256[2] memory bs, StakingShare.Stake memory stake) + returns (uint256[2] memory stakeInfo, StakingShare.Stake memory stake) { require( IERC1155Ubiquity(manager.stakingShareAddress()).balanceOf( - msg.sender, _id + msg.sender, + _id ) == 1, "Staking: caller is not owner" ); StakingShare staking = StakingShare(manager.stakingShareAddress()); - stake = staking.getStake(_id); + stake = staking.getStake(_id); require( block.number > stake.endBlock, "Staking: Redeem not allowed before staking time" ); ITWAPOracleDollar3pool(manager.twapOracleAddress()).update(); - bs = IUbiquityChef(manager.masterChefAddress()).getStakingShareInfo(_id); + stakeInfo = IUbiquityChef(manager.masterChefAddress()) + .getStakingShareInfo(_id); } } diff --git a/packages/contracts/src/dollar/StakingShare.sol b/packages/contracts/src/dollar/StakingShare.sol index b3b577b54..6ccae7339 100644 --- a/packages/contracts/src/dollar/StakingShare.sol +++ b/packages/contracts/src/dollar/StakingShare.sol @@ -71,7 +71,10 @@ contract StakingShare is /** * @dev constructor */ - constructor(UbiquityDollarManager _manager, string memory uri) ERC1155SetURI(uri) { + constructor( + UbiquityDollarManager _manager, + string memory uri + ) ERC1155SetUri(uri) { manager = _manager; } diff --git a/packages/contracts/src/dollar/UbiquityChef.sol b/packages/contracts/src/dollar/UbiquityChef.sol index adba4cbf1..8ecd22f1f 100644 --- a/packages/contracts/src/dollar/UbiquityChef.sol +++ b/packages/contracts/src/dollar/UbiquityChef.sol @@ -55,11 +55,15 @@ contract UbiquityChef is ReentrancyGuard { mapping(uint256 => StakingShareInfo) private _stakingShareInfo; event Deposit( - address indexed user, uint256 amount, uint256 indexed stakingShareId + address indexed user, + uint256 amount, + uint256 indexed stakingShareId ); event Withdraw( - address indexed user, uint256 amount, uint256 indexed stakingShareId + address indexed user, + uint256 amount, + uint256 indexed stakingShareId ); event GovernancePerBlockModified(uint256 indexed governancePerBlock); @@ -71,7 +75,10 @@ contract UbiquityChef is ReentrancyGuard { // ----------- Modifiers ----------- modifier onlyTokenManager() { require( - manager.hasRole(manager.GOVERNANCE_TOKEN_MANAGER_ROLE(), msg.sender), + manager.hasRole( + manager.GOVERNANCE_TOKEN_MANAGER_ROLE(), + msg.sender + ), "MasterChef: not Governance Token manager" ); _; @@ -120,10 +127,9 @@ contract UbiquityChef is ReentrancyGuard { } // the bigger governanceDivider is the less extra Governance Tokens will be minted for the treasury - function setGovernanceShareForTreasury(uint256 _governanceDivider) - external - onlyTokenManager - { + function setGovernanceShareForTreasury( + uint256 _governanceDivider + ) external onlyTokenManager { governanceDivider = _governanceDivider; } @@ -137,31 +143,34 @@ contract UbiquityChef is ReentrancyGuard { } // Deposit LP tokens to MasterChef for Governance Tokens allocation. - function deposit(address to, uint256 _amount, uint256 _stakingShareID) - external - nonReentrant - onlyStakingContract - { + function deposit( + address to, + uint256 _amount, + uint256 _stakingShareID + ) external nonReentrant onlyStakingContract { _deposit(to, _amount, _stakingShareID); } // Withdraw LP tokens from MasterChef. - function withdraw(address to, uint256 _amount, uint256 _stakingShareID) - external - nonReentrant - onlyStakingContract - { - StakingShareInfo storage ss = _ssInfo[_stakingShareID]; - require(ss.amount >= _amount, "MC: amount too high"); + function withdraw( + address to, + uint256 _amount, + uint256 _stakingShareID + ) external nonReentrant onlyStakingContract { + StakingShareInfo storage stakingShare = _stakingShareInfo[ + _stakingShareID + ]; + require(stakingShare.amount >= _amount, "MC: amount too high"); _updatePool(); - uint256 pending = - ((ss.amount * pool.accGovernancePerShare) / 1e12) - ss.rewardDebt; + uint256 pending = ((stakingShare.amount * pool.accGovernancePerShare) / + 1e12) - stakingShare.rewardDebt; // send Governance Tokens to Staking Share holder _safeGovernanceTransfer(to, pending); stakingShare.amount -= _amount; stakingShare.rewardDebt = - (stakingShare.amount * pool.accGovernancePerShare) / 1e12; + (stakingShare.amount * pool.accGovernancePerShare) / + 1e12; _totalShares -= _amount; emit Withdraw(to, _amount, _stakingShareID); } @@ -169,16 +178,17 @@ contract UbiquityChef is ReentrancyGuard { /// @dev get pending governance rewards from UbiquityChef. /// @return amount of pending rewards transferred to msg.sender /// @notice only send pending rewards - function getRewards(uint256 StakingShareID) external returns (uint256) { + function getRewards(uint256 stakingShareID) external returns (uint256) { require( IERC1155Ubiquity(manager.stakingShareAddress()).balanceOf( - msg.sender, stakingShareID + msg.sender, + stakingShareID ) == 1, "MS: caller is not owner" ); // calculate user reward - StakingShareInfo storage user = _stakingShareInfo[StakingShareID]; + StakingShareInfo storage user = _stakingShareInfo[stakingShareID]; _updatePool(); uint256 pending = ((user.amount * pool.accGovernancePerShare) / 1e12) - user.rewardDebt; @@ -188,19 +198,18 @@ contract UbiquityChef is ReentrancyGuard { } // View function to see pending Governance Tokens on frontend. - function pendingGovernance(uint256 stakingShareID) - external - view - returns (uint256) - { - StakingShareInfo storage user = _ssInfo[stakingShareID]; + function pendingGovernance( + uint256 stakingShareID + ) external view returns (uint256) { + StakingShareInfo storage user = _stakingShareInfo[stakingShareID]; uint256 accGovernancePerShare = pool.accGovernancePerShare; if (block.number > pool.lastRewardBlock && _totalShares != 0) { uint256 multiplier = _getMultiplier(); uint256 governanceReward = (multiplier * governancePerBlock) / 1e18; - accGovernancePerShare = accGovernancePerShare - + ((governanceReward * 1e12) / _totalShares); + accGovernancePerShare = + accGovernancePerShare + + ((governanceReward * 1e12) / _totalShares); } return (user.amount * accGovernancePerShare) / 1e12 - user.rewardDebt; } @@ -208,12 +217,13 @@ contract UbiquityChef is ReentrancyGuard { /** * @dev get the amount of shares and the reward debt of a Staking share . */ - function getStakingShareInfo(uint256 _id) - external - view - returns (uint256[2] memory) - { - return [_ssInfo[_id].amount, _ssInfo[_id].rewardDebt]; + function getStakingShareInfo( + uint256 _id + ) external view returns (uint256[2] memory) { + return [ + _stakingShareInfo[_id].amount, + _stakingShareInfo[_id].rewardDebt + ]; } /** @@ -224,18 +234,24 @@ contract UbiquityChef is ReentrancyGuard { } // _Deposit LP tokens to MasterChef for Governance Token allocation. - function _deposit(address to, uint256 _amount, uint256 _stakingShareID) - internal - { - StakingShareInfo storage ss = _ssInfo[_stakingShareID]; + function _deposit( + address to, + uint256 _amount, + uint256 _stakingShareID + ) internal { + StakingShareInfo storage stakingShare = _stakingShareInfo[ + _stakingShareID + ]; _updatePool(); - if (ss.amount > 0) { - uint256 pending = ((ss.amount * pool.accGovernancePerShare) / 1e12) - - ss.rewardDebt; + if (stakingShare.amount > 0) { + uint256 pending = ((stakingShare.amount * + pool.accGovernancePerShare) / 1e12) - stakingShare.rewardDebt; _safeGovernanceTransfer(to, pending); } - ss.amount += _amount; - ss.rewardDebt = (ss.amount * pool.accGovernancePerShare) / 1e12; + stakingShare.amount += _amount; + stakingShare.rewardDebt = + (stakingShare.amount * pool.accGovernancePerShare) / + 1e12; _totalShares += _amount; emit Deposit(to, _amount, _stakingShareID); } @@ -250,8 +266,9 @@ contract UbiquityChef is ReentrancyGuard { uint256 _amount, uint256 _stakingShareID ) internal { - StakingShareInfo storage stakingShare = - _stakingShareInfo[_stakingShareID]; + StakingShareInfo storage stakingShare = _stakingShareInfo[ + _stakingShareID + ]; stakingShare.amount += _amount; @@ -276,8 +293,10 @@ contract UbiquityChef is ReentrancyGuard { } if (isPriceDiffEnough) { - governanceMultiplier_ = - _governanceMultiply(governanceMultiplier_, currentPrice); + governanceMultiplier_ = _governanceMultiply( + governanceMultiplier_, + currentPrice + ); lastPrice_ = currentPrice; } lastPrice = lastPrice_; @@ -298,11 +317,13 @@ contract UbiquityChef is ReentrancyGuard { uint256 multiplier = _getMultiplier(); uint256 governanceReward = (multiplier * governancePerBlock) / 1e6; pool.accGovernancePerShare = - pool.accGovernancePerShare + (governanceReward / _totalShares); + pool.accGovernancePerShare + + (governanceReward / _totalShares); pool.lastRewardBlock = block.number; - pool.accGovernancePerShare = pool.accGovernancePerShare - + ((multiplier * governancePerBlock) / _totalShares / 1e6); + pool.accGovernancePerShare = + pool.accGovernancePerShare + + ((multiplier * governancePerBlock) / _totalShares / 1e6); pool.lastRewardBlock = block.number; IERC20Ubiquity(manager.governanceTokenAddress()).mint( address(this), @@ -313,21 +334,23 @@ contract UbiquityChef is ReentrancyGuard { manager.treasuryAddress(), governanceReward / governanceDivider ); - pool.accGovernancePerShare = pool.accGovernancePerShare - + ((governanceReward * 1e12) / _totalShares); + pool.accGovernancePerShare = + pool.accGovernancePerShare + + ((governanceReward * 1e12) / _totalShares); pool.lastRewardBlock = block.number; } // Safe governance transfer function, just in case if rounding // error causes pool to not have enough governance tokens. function _safeGovernanceTransfer(address _to, uint256 _amount) internal { - IERC20Ubiquity governanceToken = - IERC20Ubiquity(manager.governanceTokenAddress()); + IERC20Ubiquity governanceToken = IERC20Ubiquity( + manager.governanceTokenAddress() + ); uint256 governanceBalance = governanceToken.balanceOf(address(this)); if (_amount > governanceBalance) { - governance.safeTransfer(_to, governanceBalance); + governanceToken.safeTransfer(_to, governanceBalance); } else { - governance.safeTransfer(_to, _amount); + governanceToken.safeTransfer(_to, _amount); } } @@ -346,9 +369,12 @@ contract UbiquityChef is ReentrancyGuard { uint256 governanceMultiplier_, uint256 currentPrice ) internal view returns (uint256 multiplier) { - IUbiquityFormulas formulas = - IUbiquityFormulas(manager.formulasAddress()); - multiplier = - formulas.governanceMultiply(governanceMultiplier_, currentPrice); + IUbiquityFormulas formulas = IUbiquityFormulas( + manager.formulasAddress() + ); + multiplier = formulas.governanceMultiply( + governanceMultiplier_, + currentPrice + ); } -} \ No newline at end of file +} diff --git a/packages/contracts/src/dollar/UbiquityFormulas.sol b/packages/contracts/src/dollar/UbiquityFormulas.sol index 7582e33e8..90cd5b4d2 100644 --- a/packages/contracts/src/dollar/UbiquityFormulas.sol +++ b/packages/contracts/src/dollar/UbiquityFormulas.sol @@ -9,10 +9,10 @@ contract UbiquityFormulas is IUbiquityFormulas { using ABDKMathQuad for bytes16; /// @dev formula duration multiply - /// @param uLP , amount of LP tokens - /// @param weeks_ , minimum duration of staking period - /// @param multiplier , staking discount multiplier = 0.0001 - /// @return shares , amount of shares + /// @param _uLP , amount of LP tokens + /// @param _weeks , minimum duration of staking period + /// @param _multiplier , staking discount multiplier = 0.0001 + /// @return _shares , amount of shares /// @notice shares = (1 + multiplier * weeks^3/2) * uLP // D32 = D^3/2 // S = m * D32 * A + A @@ -22,12 +22,18 @@ contract UbiquityFormulas is IUbiquityFormulas { uint256 _multiplier ) public pure returns (uint256 _shares) { bytes16 unit = uint256(1 ether).fromUInt(); - bytes16 d = weeks_.fromUInt(); + bytes16 d = _weeks.fromUInt(); bytes16 d32 = (d.mul(d).mul(d)).sqrt(); ///bytes16 m = multiplier.fromUInt().div(unit); // 0.0001 - bytes16 a = uLP.fromUInt(); + bytes16 a = _uLP.fromUInt(); - shares = multiplier.fromUInt().mul(d32).mul(a).div(unit).add(a).toUInt(); + _shares = _multiplier + .fromUInt() + .mul(d32) + .mul(a) + .div(unit) + .add(a) + .toUInt(); } /// @dev formula bonding @@ -95,29 +101,28 @@ contract UbiquityFormulas is IUbiquityFormulas { } /// @dev formula governance multiply - /// @param multiplier , initial governance min multiplier - /// @param price , current share price - /// @return newMultiplier , new governance min multiplier + /// @param _multiplier , initial governance min multiplier + /// @param _price , current share price + /// @return _newMultiplier , new governance min multiplier /// @notice newMultiplier = multiplier * ( 1.05 / (1 + abs( 1 - price ) ) ) // nM = M * C / A // A = ( 1 + abs( 1 - P))) // 5 >= multiplier >= 0.2 - function governanceMultiply(uint256 _multiplier, uint256 _price) - public - pure - returns (uint256 _newMultiplier) - { + function governanceMultiply( + uint256 _multiplier, + uint256 _price + ) public pure returns (uint256 _newMultiplier) { bytes16 m = _multiplier.fromUInt(); bytes16 p = _price.fromUInt(); bytes16 c = uint256(105 * 1e16).fromUInt(); // 1.05 bytes16 u = uint256(1e18).fromUInt(); // 1 bytes16 a = u.add(u.sub(p).abs()); // 1 + abs( 1 - P ) - newMultiplier = m.mul(c).div(a).toUInt(); // nM = M * C / A + _newMultiplier = m.mul(c).div(a).toUInt(); // nM = M * C / A // 5 >= multiplier >= 0.2 - if (newMultiplier > 5e18 || newMultiplier < 2e17) { - newMultiplier = multiplier; + if (_newMultiplier > 5e18 || _newMultiplier < 2e17) { + _newMultiplier = _multiplier; } } } diff --git a/packages/contracts/src/dollar/core/CreditClock.sol b/packages/contracts/src/dollar/core/CreditClock.sol index 3774d0a95..b80dcf212 100644 --- a/packages/contracts/src/dollar/core/CreditClock.sol +++ b/packages/contracts/src/dollar/core/CreditClock.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.3; -import "../libs/ABDKMathQuad.sol"; +import "abdk/ABDKMathQuad.sol"; import "./UbiquityDollarManager.sol"; contract CreditClock { diff --git a/packages/contracts/src/dollar/core/CreditNFT.sol b/packages/contracts/src/dollar/core/CreditNFT.sol index 8c4d3a9a0..0b8f3a5ee 100644 --- a/packages/contracts/src/dollar/core/CreditNFT.sol +++ b/packages/contracts/src/dollar/core/CreditNFT.sol @@ -42,7 +42,9 @@ contract CreditNFT is ERC1155Ubiquity, ICreditNFT { } //@dev URI param is if we want to add an off-chain meta data uri associated with this contract - constructor(UbiquityDollarManager manager_) ERC1155Ubiquity(manager_, "URI") { + constructor( + UbiquityDollarManager manager_ + ) ERC1155Ubiquity(manager_, "URI") { _totalOutstandingDebt = 0; } @@ -83,7 +85,7 @@ contract CreditNFT is ERC1155Ubiquity, ICreditNFT { "CreditNFT owner not enough CreditNFTs" ); burn(creditNFTOwner, expiryBlockNumber, amount); - emit BurnedCreditNFTs(creditNFTOwner, expiryBlockNumber, amount); + emit BurnedCreditNFT(creditNFTOwner, expiryBlockNumber, amount); //update the total supply for that expiry and total outstanding debt _tokenSupplies[expiryBlockNumber] = @@ -108,7 +110,8 @@ contract CreditNFT is ERC1155Ubiquity, ICreditNFT { } else { //update tally and remove key from blocks and map _totalOutstandingDebt = - _totalOutstandingDebt - (_tokenSupplies[currentBlockNumber]); + _totalOutstandingDebt - + (_tokenSupplies[currentBlockNumber]); delete _tokenSupplies[currentBlockNumber]; _sortedBlockNumbers.remove(currentBlockNumber); } diff --git a/packages/contracts/src/dollar/core/DollarMintExcess.sol b/packages/contracts/src/dollar/core/DollarMintExcess.sol index c7d82124e..e4c46f877 100644 --- a/packages/contracts/src/dollar/core/DollarMintExcess.sol +++ b/packages/contracts/src/dollar/core/DollarMintExcess.sol @@ -78,41 +78,31 @@ contract DollarMintExcess is IDollarMintExcess { } // buy-back and burn GovernanceToken - function _governanceBuyBackLPAndBurn(uint256 amount) - internal - returns (uint256 amountA, uint256 amountB, uint256 liquidity) - { - bytes16 amountUAD = (amount.fromUInt()).div(uint256(2).fromUInt()); + function _governanceBuyBackLPAndBurn( + uint256 amount + ) internal returns (uint256 amountA, uint256 amountB, uint256 liquidity) { + bytes16 amountDollars = (amount.fromUInt()).div(uint256(2).fromUInt()); // we need to approve sushi router IERC20Ubiquity(manager.dollarTokenAddress()).safeApprove( address(_router), 0 ); - IERC20Ubiquity(manager.dollarTokenAddress()).safeApprove( - address(_router), - amount - ); uint256 amountGovernanceTokens = _swapDollarsForGovernance( amountDollars ); - uint256 amountGovernanceTokens = - _swapDollarsForGovernance(amountDollars); IERC20Ubiquity(manager.governanceTokenAddress()).safeApprove( address(_router), - 0 - ); - IERC20Ubiquity(manager.governanceTokenAddress()).safeApprove( - address(_router), amountGovernanceTokens + amountGovernanceTokens ); // deposit liquidity and transfer to zero address (burn) (amountA, amountB, liquidity) = _router.addLiquidity( manager.dollarTokenAddress(), manager.governanceTokenAddress(), - amountUAD.toUInt(), - amountGovernanceToken, + amountDollars.toUInt(), + amountGovernanceTokens, 0, 0, address(0), @@ -124,16 +114,17 @@ contract DollarMintExcess is IDollarMintExcess { // @param amount to convert to curve LP by swapping to 3CRV // and deposit the 3CRV as liquidity to get UbiquityDollar-3CRV LP tokens // the LP token are sent to the staking contract - function _convertToCurveLPAndTransfer(uint256 amount) - internal - returns (uint256) - { + function _convertToCurveLPAndTransfer( + uint256 amount + ) internal returns (uint256) { // we need to approve metaPool IERC20Ubiquity(manager.dollarTokenAddress()).approve( - manager.stableSwapMetaPoolAddress(), 0 + manager.stableSwapMetaPoolAddress(), + 0 ); IERC20Ubiquity(manager.dollarTokenAddress()).approve( - manager.stableSwapMetaPoolAddress(), amount + manager.stableSwapMetaPoolAddress(), + amount ); // swap amount of Ubiquity Dollar => 3CRV @@ -143,10 +134,12 @@ contract DollarMintExcess is IDollarMintExcess { // approve metapool to transfer our 3CRV IERC20(manager.curve3PoolTokenAddress()).approve( - manager.stableSwapMetaPoolAddress(), 0 + manager.stableSwapMetaPoolAddress(), + 0 ); IERC20(manager.curve3PoolTokenAddress()).approve( - manager.stableSwapMetaPoolAddress(), amount3CRVReceived + manager.stableSwapMetaPoolAddress(), + amount3CRVReceived ); // deposit liquidity diff --git a/packages/contracts/src/dollar/core/TWAPOracleDollar3pool.sol b/packages/contracts/src/dollar/core/TWAPOracleDollar3pool.sol index 0ddabe4c4..aed13ab11 100644 --- a/packages/contracts/src/dollar/core/TWAPOracleDollar3pool.sol +++ b/packages/contracts/src/dollar/core/TWAPOracleDollar3pool.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.16; import "../interfaces/IMetaPool.sol"; import "../interfaces/ITWAPOracleDollar3pool.sol"; -contract TWAPOracleDollar3pool is ITWAPOracleDollar3pool{ +contract TWAPOracleDollar3pool is ITWAPOracleDollar3pool { address public immutable pool; address public immutable token0; address public immutable token1; @@ -13,7 +13,11 @@ contract TWAPOracleDollar3pool is ITWAPOracleDollar3pool{ uint256 public pricesBlockTimestampLast; uint256[2] public priceCumulativeLast; - constructor(address _pool, address _uADtoken0, address _curve3CRVToken1) { + constructor( + address _pool, + address _dollarToken0, + address _curve3CRVToken1 + ) { pool = _pool; // coin at index 0 is uAD and index 1 is 3CRV require( @@ -22,7 +26,7 @@ contract TWAPOracleDollar3pool is ITWAPOracleDollar3pool{ "TWAPOracle: COIN_ORDER_MISMATCH" ); - token0 = _uADtoken0; + token0 = _dollarToken0; token1 = _curve3CRVToken1; uint256 _reserve0 = uint112(IMetaPool(_pool).balances(0)); @@ -53,10 +57,19 @@ contract TWAPOracleDollar3pool is ITWAPOracleDollar3pool{ ); // price to exchange amountIn uAD to 3CRV based on TWAP - UbiquityDollarPrice = IMetaPool(pool).get_dy(0, 1, 1 ether, twapBalances); + UbiquityDollarPrice = IMetaPool(pool).get_dy( + 0, + 1, + 1 ether, + twapBalances + ); // price to exchange amountIn 3CRV to uAD based on TWAP - curve3CRVAverage = - IMetaPool(pool).get_dy(1, 0, 1 ether, twapBalances); + curve3CRVAverage = IMetaPool(pool).get_dy( + 1, + 0, + 1 ether, + twapBalances + ); // we update the priceCumulative priceCumulativeLast = priceCumulative; pricesBlockTimestampLast = blockTimestamp; diff --git a/packages/contracts/src/dollar/mocks/MockBondingV1.sol b/packages/contracts/src/dollar/mocks/MockBondingV1.sol index d038f3768..20c79c245 100644 --- a/packages/contracts/src/dollar/mocks/MockBondingV1.sol +++ b/packages/contracts/src/dollar/mocks/MockBondingV1.sol @@ -238,7 +238,9 @@ contract Bonding is CollectableDust { IERC20(manager.stableSwapMetaPoolAddress()).safeTransfer( msg.sender, IUbiquityFormulas(manager.formulasAddress()).redeemShares( - _sharesAmount, _currentShareValue, ONE + _sharesAmount, + _currentShareValue, + ONE ) ); } @@ -251,8 +253,10 @@ contract Bonding is CollectableDust { uint256 totalShares = IERC1155Ubiquity(manager.stakingShareAddress()) .totalSupply(); - priceShare = IUbiquityFormulas(manager.formulasAddress()).bondPrice( - totalLP, totalShares, ONE + priceShare = IUbiquityFormulas(manager.formulasAddress()).sharePrice( + totalLP, + totalShares, + ONE ); } diff --git a/packages/contracts/test/dollar/core/CreditClock.t.sol b/packages/contracts/test/dollar/core/CreditClock.t.sol index 2c90accb1..045a96eb0 100644 --- a/packages/contracts/test/dollar/core/CreditClock.t.sol +++ b/packages/contracts/test/dollar/core/CreditClock.t.sol @@ -9,7 +9,6 @@ contract CreditClockTest is LocalTestHelper { using ABDKMathQuad for uint256; using ABDKMathQuad for bytes16; - UbiquityDollarManager manager; CreditClock creditClock; bytes16 private immutable one = uint256(1).fromUInt(); @@ -20,7 +19,7 @@ contract CreditClockTest is LocalTestHelper { bytes16 ratePerBlock ); - function setUp() public { + function setUp() public override { manager = new UbiquityDollarManager(address(this)); creditClock = new CreditClock( manager, diff --git a/packages/contracts/test/dollar/core/CreditNFT.t.sol b/packages/contracts/test/dollar/core/CreditNFT.t.sol index 1d0e82425..d37121e10 100644 --- a/packages/contracts/test/dollar/core/CreditNFT.t.sol +++ b/packages/contracts/test/dollar/core/CreditNFT.t.sol @@ -43,7 +43,7 @@ contract CreditNFTTest is LocalTestHelper { ); vm.prank(admin); vm.expectEmit(true, false, false, true); - emit MintedCreditNFTs(receiver, expiryBlockNumber, 1); + emit MintedCreditNFT(receiver, expiryBlockNumber, 1); CreditNFT(creditNFTAddress).mintCreditNFT( receiver, mintAmount, @@ -84,7 +84,7 @@ contract CreditNFTTest is LocalTestHelper { CreditNFT(creditNFTAddress).setApprovalForAll(admin, true); vm.prank(admin); vm.expectEmit(true, false, false, true); - emit BurnedCreditNFTs(creditNFTOwner, expiryBlockNumber, 1); + emit BurnedCreditNFT(creditNFTOwner, expiryBlockNumber, 1); CreditNFT(creditNFTAddress).burnCreditNFT( creditNFTOwner, burnAmount, @@ -126,4 +126,4 @@ contract CreditNFTTest is LocalTestHelper { .getTotalOutstandingDebt(); assertEq(outStandingTotalDebt, 10); } -} \ No newline at end of file +} diff --git a/packages/contracts/test/dollar/core/DollarMintExcess.t.sol b/packages/contracts/test/dollar/core/DollarMintExcess.t.sol index 35a15560f..0b15aceb7 100644 --- a/packages/contracts/test/dollar/core/DollarMintExcess.t.sol +++ b/packages/contracts/test/dollar/core/DollarMintExcess.t.sol @@ -12,7 +12,7 @@ import "../../helpers/LocalTestHelper.sol"; // exposes internal methods as external for testing contract DollarMintExcessHarness is DollarMintExcess { - constructor(address _manager) DollarMintExcess(_manager) {} + constructor(UbiquityDollarManager _manager) DollarMintExcess(_manager) {} function exposed_swapDollarsForGovernance( bytes16 amountIn @@ -33,19 +33,20 @@ contract DollarMintExcessHarness is DollarMintExcess { contract DollarMintExcessTest is LocalTestHelper { UbiquityDollarManager dollarManager; - DollarMintExcessHarness dollarMintExcess; + DollarMintExcessHarness dollarMintExcessHarness; address sushiSwapRouterAddress = 0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F; function setUp() public override { super.setUp(); - dollarManagerAddress = address(manager); - twapOracleAddress = - UbiquityDollarManager(dollarManagerAddress).twapOracleAddress(); - dollarAddress = - UbiquityDollarManager(dollarManagerAddress).dollarTokenAddress(); - excessDollarsDistributorAddress = - address(new DollarMintExcess(manager)); + dollarMintExcessHarness = new DollarMintExcessHarness(manager); + address dollarManagerAddress = address(manager); + address twapOracleAddress = UbiquityDollarManager(dollarManagerAddress) + .twapOracleAddress(); + address dollarAddress = manager.dollarTokenAddress(); + address excessDollarsDistributorAddress = address( + new DollarMintExcess(manager) + ); } function testDistributeDollars_ShouldTransferTokens() public { @@ -134,7 +135,7 @@ contract DollarMintExcessTest is LocalTestHelper { ); // make a swap assertEq( - dollarMintExcess.exposed_swapDollarsForGovernance( + dollarMintExcessHarness.exposed_swapDollarsForGovernance( bytes16(0x00000000000000000000000000000001) ), 1 ether @@ -178,7 +179,7 @@ contract DollarMintExcessTest is LocalTestHelper { ) ) ); - dollarMintExcess.exposed_governanceBuyBackLPAndBurn(1 ether); + dollarMintExcessHarness.exposed_governanceBuyBackLPAndBurn(1 ether); } function testConvertToCurveLPAndTransfer_ShouldAddLiquidity() public { @@ -186,7 +187,7 @@ contract DollarMintExcessTest is LocalTestHelper { address stableSwapMetaPoolAddress = address(0x01); address curve3PoolTokenAddress = address(0x02); vm.prank(admin); - manager.setStableSwapMetaPoolAddress(_metaPoolAddress); + manager.setStableSwapMetaPoolAddress(stableSwapMetaPoolAddress); vm.mockCall( stableSwapMetaPoolAddress, abi.encodeWithSelector(IMetaPool.exchange.selector), @@ -213,7 +214,9 @@ contract DollarMintExcessTest is LocalTestHelper { // add liquidity assertEq( - dollarMintExcess.exposed_convertToCurveLPAndTransfer(1 ether), + dollarMintExcessHarness.exposed_convertToCurveLPAndTransfer( + 1 ether + ), 1 ether ); } diff --git a/packages/contracts/test/helpers/LocalTestHelper.sol b/packages/contracts/test/helpers/LocalTestHelper.sol index cb4ceed2f..8d86d0f17 100644 --- a/packages/contracts/test/helpers/LocalTestHelper.sol +++ b/packages/contracts/test/helpers/LocalTestHelper.sol @@ -5,6 +5,7 @@ import {UbiquityDollarManager} from "../../src/dollar/core/UbiquityDollarManager import {UbiquityGovernanceToken} from "../../src/dollar/core/UbiquityGovernanceToken.sol"; import {CreditRedemptionCalculator} from "../../src/dollar/core/CreditRedemptionCalculator.sol"; import {CreditNFTRedemptionCalculator} from "../../src/dollar/core/CreditNFTRedemptionCalculator.sol"; +import {CreditNFTManager} from "../../src/dollar/core/CreditNFTManager.sol"; import {DollarMintCalculator} from "../../src/dollar/core/DollarMintCalculator.sol"; import {DollarMintExcess} from "../../src/dollar/core/DollarMintExcess.sol"; import {MockCreditNFT} from "../../src/dollar/mocks/MockCreditNFT.sol"; @@ -80,9 +81,7 @@ abstract contract LocalTestHelper is Test { manager.setCreditTokenAddress(address(creditToken)); // deploy CreditRedemptionCalculator - creditRedemptionCalculator = new CreditRedemptionCalculator( - manager - ); + creditRedemptionCalculator = new CreditRedemptionCalculator(manager); manager.setCreditCalculatorAddress(address(creditRedemptionCalculator)); // deploy DollarMintCalculator