Farseen0/scar-pairs huggingface dataset:
MEDIUM severity: The `ProposalType` enum is defined in the RocketDAOProtocolProposals and RocketDAONodeTrustedProposa. The `ProposalType` enum is defined in the RocketDAOProtocolProposals and RocketDAONodeTrustedProposals, but it is not utilized anywhere in the code. This unused enum contains four possible proposal types: `Invite`, `Leave`, `Replace`, `Kick`, and `Setting`. The `Setting` type is duplicated in the tw...

Vulnerable code:
```\nenum ProposalType {\n    Invite,             // Invite a registered node to join the trusted node DAO\n    Leave,              // Leave the DAO\n    Replace,            // Replace a current trusted node with a new registered node, they take over their bond\n    Kick,               // Kick a member from the DAO with optional penalty applied to their RPL deposit\n    Setting             // Change a DAO setting (Quorum threshold, RPL deposit size, voting periods etc)\n}\n```\n```\nenum ProposalType:\n    Setting  # Change a DAO setting (Node operator min/max fees, inflation rate etc)\n```
MEDIUM severity: The `Unused parameter in BasketManager._addBasket` vulnerability refers to a potential security issu. The `Unused parameter in BasketManager._addBasket` vulnerability refers to a potential security issue in the `_addBasket` method of the `BasketManager` class. Specifically, the `_measurementMultiple` parameter is always set to `StableMath.getRatioScale()` which is equal to 1e8. This constant value i...

Vulnerable code:
```\nrequire(_measurementMultiple >= 1e6 && _measurementMultiple <= 1e10,\n        "MM out of range");\n```
MEDIUM severity: The vulnerability allows node operators to reduce the impact of slashing by withdrawing excess stake. The vulnerability allows node operators to reduce the impact of slashing by withdrawing excess staked RPL. This is achieved by manipulating the staking end balance and user deposit balance to minimize the amount of RPL that needs to be slashed. The slashing amount is calculated as the difference bet...

Vulnerable code:
```\nrocketMinipoolManager.setMinipoolWithdrawalBalances(_minipoolAddress, _stakingEndBalance, nodeAmount);\n\nif (_stakingEndBalance < userDepositBalance):\n    rocketNodeStaking = RocketNodeStakingInterface(getContractAddress("rocketNodeStaking"))\n    rocketNodeStaking.slashRPL(minipool.getNodeAddress(), userDepositBalance - _stakingEndBalance)\n```\n```\nuint256 rplSlashAmount = calcBase.mul(_ethSlashAmount).div(rocketNetworkPrices.getRPLPrice());\n\n// Cap slashed amount to node's RPL stake\nuint256 rplStake = getNodeRPLStake(_nodeAddress);\nif (rplSlashAmount > rplStake) {\n    rplSlashAmount = rplStake;\n}\n\n// Transfer slashed amount to auction contract\nrocketVault.transferToken("rocketAuctionManager", getContractAddress("rocketTokenRPL"), rplSlashAmount);\n\n// Update RPL stake amounts\ndecreaseTotalRPLStake(rplSlashAmount);\ndecreaseNodeRPLStake(_nodeAddress, rplSlashAmount);\n```\n```\nreturn rocketDAOProtocolSettingsMinipool.getHalfDepositUserAmount()\n   .mul(rocketDAOProtocolSettingsNode.getMinimumPerMinipoolStake())\n   .mul(rocketMinipoolManager.getNodeMinipoolCount(_nodeAddress))\n   .div(rocketNetworkPrices.getRPLPrice());\n```
MEDIUM severity: The VoteMachine's `cancelVoteByRelayer` function allows an attacker to cancel a vote by providing th. The VoteMachine's `cancelVoteByRelayer` function allows an attacker to cancel a vote by providing the proposal ID, nonce, voter's address, signature, and a hash of the sent parameters. The function correctly verifies the hashed parameters against the provided signature and checks the nonce to ensure...

Vulnerable code:
```\nrequire(\n    _proposal.voters[_voter].nonce < _relayerNonce,\n    "INVALID_NONCE"\n);\n```\n```\nif (_cachedVoter.balance > 0) {\n    _proposal.votes[_cachedVoter.vote] = \n        _proposal.votes[_cachedVoter.vote].sub(_cachedVoter.balance.mul(_cachedVoter.weight));\n    _proposal.totalVotes = _proposal.totalVotes.sub(1);\n    voter.weight = 0;\n    voter.balance = 0;\n    voter.vote = 0;\n    voter.asset = address(0);\n    emit VoteCancelled(\n        _proposalId,\n        _voter,\n        _cachedVoter.vote,\n        _cachedVoter.asset,\n        _cachedVoter.weight,\n        _cachedVoter.balance,\n        uint256(_proposal.proposalStatus)\n    );\n}\n```
MEDIUM severity: The vulnerability arises from an incorrect update to the `ownerToRollOverQueueIndex` variable when a. The vulnerability arises from an incorrect update to the `ownerToRollOverQueueIndex` variable when an existing rollover is present. Specifically, the `ownerToRollOverQueueIndex` is updated to point to the last item in the `rolloverQueue` array, regardless of whether the user has an existing rollover...

Vulnerable code:
```\nif (ownerToRollOverQueueIndex[_receiver]!= 0) {\n    uint256 index = getRolloverIndex(_receiver);\n    rolloverQueue[index].assets = _assets;\n    rolloverQueue[index].epochId = _epochId;\n}\n```\n```\nownerToRollOverQueueIndex[_receiver] = rolloverQueue.length\n```\n```\nQueueItem memory item = rolloverQueue[getRolloverIndex(_receiver)];\nif (\n    item.epochId == _epochId &&\n    (balanceOf(_receiver, _epochId) - item.assets) < _assets\n) {\n    revert AlreadyRollingOver();\n}\n```
MEDIUM severity: The GovernanceTimelock contract, responsible for Roles Based Access Control management in the Lybra . The GovernanceTimelock contract, responsible for Roles Based Access Control management in the Lybra Protocol, contains a critical vulnerability that grants the deployer of the contract, and the contract itself, excessive privileges. The `checkRole` function allows an address with the `DAO` role to b...

Vulnerable code:
```\nfunction checkRole(bytes32 role, address _sender) public view returns(bool) {\n    return hasRole(role, _sender) || hasRole(DAO, _sender);\n}\n\nfunction checkOnlyRole(bytes32 role, address _sender) public view returns(bool) {\n    return hasRole(role, _sender);\n}\n```\n```\nconstructor(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) public TimelockController(minDelay, proposers, executors, admin) {\n    _setRoleAdmin(DAO, GOV);\n    _setRoleAdmin(TIMELOCK, GOV);\n    _setRoleAdmin(ADMIN, GOV);\n    _grantRole(DAO, address(this));\n    _grantRole(DAO, msg.sender);\n    _grantRole(GOV, msg.sender);\n}\n```
MEDIUM severity: The `_updateVirtualPrice` function in the Vault_Base_ERC20 contract is responsible for updating the . The `_updateVirtualPrice` function in the Vault_Base_ERC20 contract is responsible for updating the virtual price of an asset in discrete increments of 3 minutes. This is done to mitigate the risk of denial-of-service (DoS) attacks. However, the function has a critical flaw that allows for the manip...

Vulnerable code:
```\nfunction _updateVirtualPrice(uint256 _currentBlockTime, address _collateralAddress) internal {\n    (\n        uint256 interestPer3Min,\n        uint256 lastUpdateTime,\n        uint256 virtualPrice,\n       ,\n       ,\n        uint256 collateralBalance\n    ) = _getCollateral(_collateralAddress);\n\n    uint256 timeDelta = _currentBlockTime - lastUpdateTime;\n    //exit gracefully if two users call the function for the same collateral in the same 3min period\n    uint256 threeMinuteDelta = timeDelta / 180;\n\n    if (threeMinuteDelta > 0) {\n        for (uint256 i = 0; i < threeMinuteDelta; i++) {\n            virtualPrice = (virtualPrice * interestPer3Min) / LOAN_SCALE;\n        }\n        collateralBook.vaultUpdateVirtualPriceAndTime(_collateralAddress, virtualPrice, _currentBlockTime);\n    }\n}\n```
MEDIUM severity: This vulnerability allows for a denial-of-service (DoS) attack on the withdrawal process by exploiti. This vulnerability allows for a denial-of-service (DoS) attack on the withdrawal process by exploiting the gas consumption of a malicious smart contract. The issue lies in the `processWithdrawals` function, which does not properly account for the gas consumption of the withdrawal queue. An attacker...

Vulnerable code:
```\npragma solidity 0.8.9;\n\nimport "./Utils.sol";\n\ncontract MaliciousReceiver {\n    uint256 public gas;\n    receive() payable external {\n        gas = gasleft();\n        for (uint256 i = 0; i < 150000; i++) {}\n    }\n}\n\ncontract VUSDWithReceiveTest is Utils {\n    event WithdrawalFailed(address indexed trader, uint amount, bytes data);\n\n    function setUp() public {\n        setupContracts();\n    }\n\n    function test_CannotProcessWithdrawals(uint128 amount) public {\n        MaliciousReceiver r = new MaliciousReceiver();\n\n        vm.assume(amount >= 5e6);\n        mintVusd(address(this), amount);\n        mintVusd(alice, amount);\n        mintVusd(bob, amount);\n\n        husd.withdraw(amount); // first withdraw in the array\n        vm.prank(alice);\n        husd.withdraw(amount);\n        vm.prank(bob);\n        husd.withdrawTo(address(r), amount);\n\n        assertEq(husd.withdrawalQLength(), 3);\n        assertEq(husd.start(), 0);\n\n        husd.processWithdrawals();\n\n        uint256 ethereumSoftGasLimit = 30_000_000;\n        assertGt(r.gas(), ethereumSoftGasLimit);\n    }\n\n    receive() payable external {\n        assertEq(msg.sender, address(husd));\n    }\n}\n```
MEDIUM severity: The `calculateAmountOwed()` function in the loan repayment process employs a ternary logic that may . The `calculateAmountOwed()` function in the loan repayment process employs a ternary logic that may incorrectly calculate the last EMI payment, potentially leading to the borrower failing to pay the owed principal and subsequently losing their collaterals. This scenario arises when the borrower make...

Vulnerable code:
```\nelse {\n    // Default to PaymentType.EMI\n    uint256 maxCycleOwed = isLastPaymentCycle\n       ? owedPrincipal_ + interest_\n        : _bid.terms.paymentCycleAmount;\n\n    // Calculate accrued amount due since last repayment\n    uint256 owedAmount = (maxCycleOwed * owedTime) / _bid.terms.paymentCycle;\n    duePrincipal_ = Math.min(owedAmount - interest_, owedPrincipal_);\n}\n```\n```\nif (paymentAmount >= _owedAmount) {\n    paymentAmount = _owedAmount;\n    bid.state = BidState.PAID;\n\n    // Remove borrower's active bid\n    _borrowerBidsActive[bid.borrower].remove(_bidId);\n\n    if (_shouldWithdrawCollateral) {\n        collateralManager.withdraw(_bidId);\n    }\n\n    emit LoanRepaid(_bidId);\n```
MEDIUM severity: The `Uniproxy.depositSwap` function in the UniProxy contract is vulnerable to a potential attack due. The `Uniproxy.depositSwap` function in the UniProxy contract is vulnerable to a potential attack due to the fact that the `_router` variable is determined by the caller. This allows an attacker to inject a "fake" contract, which can potentially steal funds stuck in the UniProxy contract.\n\nThe UniP...

Vulnerable code:
```\nfunction depositSwap(\n    int256 swapAmount, // (-) token1, (+) token0 for token1; amount to swap\n    uint256 deposit0,\n    uint256 deposit1,\n    address to,\n    address from,\n    bytes memory path,\n    address pos,\n    address _router\n) external returns (uint256 shares) {\n```
MEDIUM severity: The `tbtc` protocol's `increaseRedemptionFee` mechanism allows signers to approve a signable bitcoin. The `tbtc` protocol's `increaseRedemptionFee` mechanism allows signers to approve a signable bitcoin transaction with a higher fee in response to network congestion. This feature enables fee increases every 4 hours, with each increment requiring an exact increase of the initial proposed fee. However...

Vulnerable code:
```\nrequire(block.timestamp >= _d.withdrawalRequestTime + TBTCConstants.getIncreaseFeeTimer(), "Fee increase not yet permitted");\n```\n```\nuint256 _previousOutputValue = DepositUtils.bytes8LEToUint(_previousOutputValueBytes);\n_newOutputValue = DepositUtils.bytes8LEToUint(_newOutputValueBytes);\nrequire(_previousOutputValue.sub(_newOutputValue) == _d.initialRedemptionFee, "Not an allowed fee step");\n```
MEDIUM severity: The `getCommunityVotingPower` function in the `Staking.sol` contract is susceptible to precision los. The `getCommunityVotingPower` function in the `Staking.sol` contract is susceptible to precision loss due to the manner in which it calculates the voting power. Specifically, the function multiplies the `votes`, `proposalsCreated`, and `proposalsPassed` variables by their respective multipliers (`cp...

Vulnerable code:
```\nreturn (\n    votes * cpMultipliers.votes / PERCENT +\n    proposalsCreated * cpMultipliers.proposalsCreated / PERCENT +\n    proposalsPassed * cpMultipliers.proposalsPassed / PERCENT);\n```
MEDIUM severity: The `MultiInvoker._latest` function returns a price of 0 when the latest oracle version is invalid, . The `MultiInvoker._latest` function returns a price of 0 when the latest oracle version is invalid, which can lead to two critical issues. Firstly, liquidation orders will send a 0 liquidation fee to the liquidator, effectively allowing the liquidator to liquidate positions for free. Secondly, some...

Vulnerable code:
```\nOracleVersion memory latestOracleVersion = market.oracle().latest();\nlatestPrice = latestOracleVersion.price;\nIPayoffProvider payoff = market.payoff();\nif (address(payoff)!= address(0)) {\n    latestPrice = payoff.payoff(latestPrice);\n}\n```\n```\nfunction _commitRequested(OracleVersion memory version) private returns (bool) {\n    if (block.timestamp <= (next() + timeout)) {\n        if (!version.valid) {\n            revert KeeperOracleInvalidPriceError();\n        }\n        _prices[version.timestamp] = version.price;\n    }\n    _global.latestIndex++;\n    return true;\n}\n```\n```\nfunction _liquidationFee(\n    IMarket market,\n    address account\n) internal view returns (Position memory, UFixed6, UFixed6) {\n    RiskParameter memory riskParameter = market.riskParameter();\n\n    (Position memory latestPosition, Fixed6 latestPrice, UFixed6 closableAmount) = _latest(market, account);\n\n    Order memory placeholderOrder;\n    placeholderOrder.maker = Fixed6Lib.from(closableAmount);\n\n    return (\n        latestPosition,\n        placeholderOrder\n           .liquidationFee(\n                OracleVersion(latestPosition.timestamp, latestPrice, true),\n                riskParameter\n            )\n           .min(UFixed6Lib.from(market.token().balanceOf(address(market)))),\n        closableAmount\n    );\n}\n```\n```\nfunction _liquidate(\n    IMarket market,\n    address account,\n    bool revertOnFailure\n) internal isMarketInstance(market) {\n    (\n        Position memory latestPosition,\n        UFixed6 liquidationFee,\n        UFixed6 closable\n    ) = _liquidationFee(market, account);\n\n    Position memory currentPosition = market.pendingPositions(account, market.locals(account).currentId);\n    currentPosition.adjust(latestPosition);\n\n    try market.update(\n        account,\n        currentPosition.maker.isZero()? UFixed6Lib.ZERO : currentPosition.maker.sub(closable),\n        currentPosition.long.isZero()? UFixed6Lib.ZERO : currentPosition.long.sub(closable),\n        currentPosition.short.isZero()? UFixed6Lib.ZERO : currentPosition.short.sub(closable),\n        Fixed6Lib.from(-1, liquidationFee),\n        true\n    )\n```\n```\nfunction _executeOrder(address account, IMarket market, uint256 nonce) internal {\n    if (!canExecuteOrder(account, market, nonce)) revert MultiInvokerCantExecuteError();\n}\n\nfunction canExecuteOrder(address account, IMarket market, uint256 nonce) public view returns (bool) {\n    TriggerOrder memory order = orders(account, market, nonce);\n    if (order.fee.isZero()) return false;\n    (, Fixed6 latestPrice, ) = _latest(market, account);\n    return order.fillable(latestPrice);\n}\n```
MEDIUM severity: The Curve LP Controller's `WITHDRAWCLAIM` function in both CurveLPStakingController.sol and Balancer. The Curve LP Controller's `WITHDRAWCLAIM` function in both CurveLPStakingController.sol and BalancerLPStakingController.sol contracts employs an incorrect function signature, resulting in the function's failure to execute successfully. The function selector `0x00ebf5dd` is mistakenly used for `WITHD...

Vulnerable code:
```\nbytes4 constant WITHDRAWCLAIM = 0x00ebf5dd;\n```
MEDIUM severity: The `initialize` function of the Portal contract is designed to be initialized by a specific entity,. The `initialize` function of the Portal contract is designed to be initialized by a specific entity, referred to as the `_GOVERNANCE`. This entity is passed as a parameter to the `initialize` function and is used to set various variables within the contract. Specifically, the `_GOVERNANCE` is assign...

Vulnerable code:
```\nfunction initialize(\n    address _GOVERNANCE,\n    address _gETH,\n    address _ORACLE_POSITION,\n    address _DEFAULT_gETH_INTERFACE,\n    address _DEFAULT_DWP,\n    address _DEFAULT_LP_TOKEN,\n    address _MINI_GOVERNANCE_POSITION,\n    uint256 _GOVERNANCE_TAX,\n    uint256 _COMET_TAX,\n    uint256 _MAX_MAINTAINER_FEE,\n    uint256 _BOOSTRAP_PERIOD\n) public virtual override initializer {\n    _ReentrancyGuard_init();\n    _Pausable_init();\n    _ERC1155Holder_init();\n    _UUPSUpgradeable_init();\n\n    GEODE.SENATE = _GOVERNANCE;\n    GEODE.GOVERNANCE = _GOVERNANCE;\n    GEODE.GOVERNANCE_TAX = _GOVERNANCE_TAX;\n    GEODE.MAX_GOVERNANCE_TAX = _GOVERNANCE_TAX;\n    GEODE.SENATE_EXPIRY = type(uint256).max;\n\n    STAKEPOOL.GOVERNANCE = _GOVERNANCE;\n    STAKEPOOL.gETH = IgETH(_gETH);\n    STAKEPOOL.TELESCOPE.gETH = IgETH(_gETH);\n    STAKEPOOL.TELESCOPE.ORACLE_POSITION = _ORACLE_POSITION;\n    STAKEPOOL.TELESCOPE.MONOPOLY_THRESHOLD = 20000;\n\n    updateStakingParams(\n        _DEFAULT_gETH_INTERFACE,\n        _DEFAULT_DWP,\n        _DEFAULT_LP_TOKEN,\n        _MAX_MAINTAINER_FEE,\n        _BOOSTRAP_PERIOD,\n        type(uint256).max,\n        type(uint256).max,\n        _COMET_TAX,\n        3 days\n    );\n}\n```\n```\nfunction updateStakingParams(\n    address _DEFAULT_gETH_INTERFACE,\n    address _DEFAULT_DWP,\n    address _DEFAULT_LP_TOKEN,\n    uint256 _MAX_MAINTAINER_FEE,\n    uint256 _BOOSTRAP_PERIOD,\n    uint256 _PERIOD_PRICE_INCREASE_LIMIT,\n    uint256 _PERIOD_PRICE_DECREASE_LIMIT,\n    uint256 _COMET_TAX,\n    uint256 _BOOST_SWITCH_LATENCY\n) public virtual override {\n    require(\n        msg.sender == GEODE.GOVERNANCE,\n        "Portal: sender not GOVERNANCE"\n    );\n}\n```
MEDIUM severity: The `ZrxVaultBackstop` contract is vulnerable to a denial-of-service (DoS) attack, which can indefin. The `ZrxVaultBackstop` contract is vulnerable to a denial-of-service (DoS) attack, which can indefinitely stall the catastrophic failure mode activation. This vulnerability arises from the `StakingProxy` contract's ability to track the last timestamp at which "read-only" mode was activated. Specific...

Vulnerable code:
```\nfunction setReadOnlyMode(bool shouldSetReadOnlyMode)\n    external\n    onlyAuthorized\n{\n    uint96 timestamp = block.timestamp.downcastToUint96();\n    if (shouldSetReadOnlyMode) {\n        stakingContract = readOnlyProxy;\n        readOnlyState = IStructs.ReadOnlyState({\n            isReadOnlyModeSet: true,\n            lastSetTimestamp: timestamp\n        });\n}\n```
MEDIUM severity: The vulnerability occurs when the underlying asset of LEther is set to `address(0)`, which is allowe. The vulnerability occurs when the underlying asset of LEther is set to `address(0)`, which is allowed by the logic in `AccountManager#settle()` and `RiskEngine#_valueInWei()`. This special handling of `address(0)` as an asset implies that it can be used as a valid underlying asset.\n\nHowever, when...

Vulnerable code:
```\nfunction borrow(address account, address token, uint amt)\n    external\n    whenNotPaused\n    onlyOwner(account)\n{\n    if (registry.LTokenFor(token) == address(0))\n        revert Errors.LTokenUnavailable();\n\n    if (!riskEngine.isBorrowAllowed(account, token, amt))\n        revert Errors.RiskThresholdBreached();\n\n    if (IAccount(account).hasAsset(token) == false)\n        IAccount(account).addAsset(token);\n\n    if (ILToken(registry.LTokenFor(token)).lendTo(account, amt))\n        IAccount(account).addBorrow(token);\n\n    emit Borrow(account, msg.sender, token, amt);\n}\n```\n```\nfunction liquidate(address account) external {\n    if (riskEngine.isAccountHealthy(account)) {\n        revert Errors.AccountNotLiquidatable();\n    }\n    _liquidate(account);\n    emit AccountLiquidated(account, registry.ownerFor(account));\n}\n```\n```\nfunction _getBalance(address account) internal view returns (uint) {\n    address[] memory assets = IAccount(account).getAssets();\n    uint assetsLen = assets.length;\n    uint totalBalance;\n    for (uint i = 0; i < assetsLen; ++i) {\n        totalBalance += _valueInWei(assets[i], IERC20(assets[i]).balanceOf(account));\n    }\n    return totalBalance + account.balance;\n}\n```
MEDIUM severity: The vulnerability allows an attacker to front-run a lender's transaction, leading to the loss of fun. The vulnerability allows an attacker to front-run a lender's transaction, leading to the loss of funds. This occurs when a lender attempts to mint a share larger than the maximum available `maxFCash` by setting a `minImpliedRate` to protect against trade slippage. However, if the attacker successful...

Vulnerable code:
```\nfunction mintViaUnderlying(\n    uint256 depositAmountExternal,\n    uint88 fCashAmount,\n    address receiver,\n    uint32 minImpliedRate\n) external override {\n    (, uint256 maxFCash) = getTotalFCashAvailable();\n    _mintInternal(depositAmountExternal, fCashAmount, receiver, minImpliedRate, maxFCash);\n}\n```\n```\nif (maxFCash < fCashAmount) {\n    uint256 fCashAmountExternal = fCashAmount * precision / uint256(Constants.INTERNAL_TOKEN_PRECISION);\n    require(fCashAmountExternal <= depositAmountExternal);\n\n    NotionalV2.depositUnderlyingToken{value: msgValue}(address(this), currencyId, fCashAmountExternal);\n}\n```\n```\nfunction testDepositViaUnderlying() public {\n    address alice = makeAddr("alice");\n    deal(address(asset), LENDER, 8800 * precision, true);\n    deal(address(asset), alice, 5000 * precision, true);\n\n    vm.stopPrank();\n    vm.startPrank(alice);\n    asset.approve(address(w), type(uint256).max);\n\n    // LENDER START\n    vm.stopPrank();\n    vm.startPrank(LENDER);\n    asset.approve(address(w), type(uint256).max);\n    assertEq(asset.balanceOf(LENDER), 8800e18);\n\n    (/* */, uint256 maxFCash) = w.getTotalFCashAvailable();\n    console2.log("current maxFCash:", maxFCash);\n\n    uint32 minImpliedRate = 0.15e9;\n    vm.expectRevert("Trade failed, slippage");\n    w.mintViaUnderlying(5000e18, 5000e8, LENDER, minImpliedRate);\n\n    // LENDER END\n\n    // alice frontrun to mint some shares.\n    vm.stopPrank();\n    vm.startPrank(alice);\n    w.mint(5000e8, alice);\n\n    // LENDER TX\n    vm.stopPrank();\n    vm.startPrank(LENDER);\n    asset.approve(address(w), type(uint256).max);\n    assertEq(asset.balanceOf(LENDER), 8800e18);\n\n    // LENDER mintViaUnderlying will success.\n    w.mintViaUnderlying(5000e18, 5000e8, LENDER, minImpliedRate);\n\n    console2.log("lender mint token:", w.balanceOf(LENDER));\n    console2.log("lender cost DAI:", 8800e18 - asset.balanceOf(LENDER));\n}\n```