Farseen0/scar-pairs huggingface dataset:
MEDIUM severity: SUP rewards for depositing TBYs can be gamed by depositing TBYs that are close to expiration. **Details**

[StUsdc.sol#L118-L130](https://github.com/stakeup-protocol/stakeup-contracts/blob/b4d8a83e9455efb8c7543a0fc62b5aea598c7f49/src/token/StUsdc.sol#L118-L130)

    function depositTby(uint256 tbyId, uint256 amount) external nonReentrant returns (uint256 amountMinted) {
        IBloomPool...

Vulnerable code:
function depositTby(uint256 tbyId, uint256 amount) external nonReentrant returns (uint256 amountMinted) {
IBloomPool pool = _bloomPool;
require(amount > 0, Errors.ZeroAmount());
require(!pool.isTbyRedeemable(tbyId), Errors.RedeemableTbyNotAllowed());
// If the token is a TBY, we need to get the current exchange rate of the token
//     to accurately calculate the amount of stUsdc to mint.
amountMinted = pool.getRate(tbyId).mulWad(amount) * _scalingFactor;
_deposit(amountMinted);
_mintRewards(amountMinted);

emit TbyDeposited(msg.sender, tbyId, amount, amountMinted);
_tby.safeTransferFrom(msg.sender, address(this), tbyId, amount, "");
}
HIGH severity: Donations to MarketMaker will completely freeze all buy/sell capability of market. **Details**

[MarketMaker.sol#L672-L679](https://github.com/SportsFI-UBet/ubet-contracts-v1/blob/64157824f67d6000588ae4235a49ccd24dede5c3/contracts/markets/MarketMaker.sol#L672-L679)

    function getTargetBalance()
        public
        view
        returns (AmmMath.TargetContext memory...

Vulnerable code:
function getTargetBalance()
public
view
returns (AmmMath.TargetContext memory targetContext, uint256[] memory fairPriceDecimals)
{
// The logic is such that any excess collateral is always returned to the parent
uint256 localReserves = reserves();
assert(localReserves == 0);

function buyFor(
...
) public returns (uint256 outcomeTokensBought, uint256 feeAmount, uint256[] memory spontaneousPrices) {
if (isHalted()) revert MarketHalted();
if (investmentAmount < minInvestment) revert InvalidInvestmentAmount();

uint256 tokensToMint;
uint256 refundIndex;
AmmMath.ParentOperations memory parentOps;
{
(AmmMath.TargetContext memory targetContext, uint256[] memory fairPriceDecimals) = getTargetBalance();
refundIndex = AmmMath.getRefundIndex(targetContext);
(outcomeTokensBought, tokensToMint, feeAmount, spontaneousPrices, parentOps) =
_calcBuyAmount(investmentAmount, outcomeIndex, extraFeeDecimal, targetContext, fairPriceDecimals);
}
HIGH severity: Frontrunning or reorg attacks can be used to corrupt initial pricing data to drain funds from MarketMaker. **Details**

[ConditionalTokens.sol#L92-L131](https://github.com/SportsFI-UBet/ubet-contracts-v1/blob/64157824f67d6000588ae4235a49ccd24dede5c3/contracts/conditions/ConditionalTokens.sol#L92-L131)

    function prepareCondition(
        ...
    ) public returns (ConditionID) {
        // Limit of...

Vulnerable code:
function prepareCondition(
...
) public returns (ConditionID) {
// Limit of 256 because we use a partition array that is a number of 256 bits.
if (outcomeSlotCount < 2 || outcomeSlotCount > 255) revert InvalidOutcomeSlotsAmount();

// If not prepared, initialize, and emit the event, otherwise just return existing conditionId
if (payoutNumerators[conditionId].length == 0) {
payoutNumerators[conditionId] = new uint256[](outcomeSlotCount);

if (priceOracle != address(0x0)) {
// Packed prices cannot be longer than number of outcome slots.
// However, if they are shorter, the missing trailing values are
// assumed to be 0.
if (packedPrices.length > outcomeSlotCount * 2) revert InvalidPrices();
uint256 total = PackedPrices.sum(packedPrices);
if (total != PackedPrices.DIVISOR) revert InvalidPrices();
HIGH severity: Sending child shares before burning shares allow reentrancy vulnerability in ParentFundingPool#removeChildShares. **Details**

    [MarketMaker.sol#L268-L274](https://github.com/SportsFI-UBet/ubet-contracts-v1/blob/64157824f67d6000588ae4235a49ccd24dede5c3/contracts/markets/MarketMaker.sol#L268-L274)

    function _afterTokenTransfer(address from, address to, uint256 amount) internal override {
        // When.....

Vulnerable code:
function _afterTokenTransfer(address from, address to, uint256 amount) internal override {
// When address other than parent gets shares, immediately eject them to
// maintain invariant that all funding is by parent
if (from == getParentPool() && to != address(0x0)) {
_removeFunding(to, amount);
}
}

function _removeFunding(address funder, uint256 sharesToBurn)
private
returns (uint256 collateral, uint256[] memory sendAmounts)
{
(collateral, sendAmounts) = _calcRemoveFunding(sharesToBurn);
_burnSharesOf(funder, sharesToBurn);

collateralToken.safeTransfer(funder, collateral);
uint256 outcomeSlotCount = sendAmounts.length;
conditionalTokens.safeBatchTransferFrom(
address(this),
funder,
CTHelpers.getPositionIds(collateralToken, conditionId, outcomeSlotCount),
sendAmounts,
""
);
...
}
MEDIUM severity: Fees will be lost in the event that a user withdraws from MarketFundingPool and there isn't enough reserves to cover fees. **Details**

[ParentFundingPool.sol#L631-L646](https://github.com/SportsFI-UBet/ubet-contracts-v1/blob/64157824f67d6000588ae4235a49ccd24dede5c3/contracts/funding/ParentFundingPool.sol#L631-L646)

    function _reevaluateGainsOnPool(bool force) private returns (uint256 fees) {
        uint256...

Vulnerable code:
function _reevaluateGainsOnPool(bool force) private returns (uint256 fees) {
uint256 lastBlock = lastFeeEvaluationBlock;
uint256 period = feeEvaluationBlockPeriod;
if (!force && (block.number - lastBlock <= period)) return fees;

lastFeeEvaluationBlock = uint64(block.number);
uint256 poolValue = getPoolValue();
if (poolValue <= valueHighPoint) return fees;

uint256 gains = poolValue - valueHighPoint;
// Prevent taking more fees than available collateral
fees = Math.min(reserves(), (gains * feePortion) / 256); <- fees minimized
MEDIUM severity: ParentFundingPool#removeCollateral fails to update valueHighPoint resulting in lost fees. **Details**

[ParentFundingPool.sol#L233-L251](https://github.com/SportsFI-UBet/ubet-contracts-v1/blob/64157824f67d6000588ae4235a49ccd24dede5c3/contracts/funding/ParentFundingPool.sol#L233-L251)

    function removeCollateral(uint256 sharesToBurn)
        external
        whenNotPaused
       ...

Vulnerable code:
function removeCollateral(uint256 sharesToBurn)
external
whenNotPaused
returns (uint256 collateralReturned, uint256 sharesBurnt)
{
address funder = _msgSender();
// force re-evaluation because some value is exiting
_reevaluateGainsOnPool(true);

uint256[] memory noTokens = new uint256[](0);
emit FundingRemoved(funder, collateralReturned, noTokens, sharesBurnt);
}
HIGH severity: `RewardDistributor#claim` will revert for tokens with expired locks leading to loss of rewards. **Details**

[RewardsDistributor.sol#L277-L287](https://github.com/hyperstable/contracts/blob/35db5f2d3c8c1adac30758357fbbcfe55f0144a3/src/governance/RewardsDistributor.sol#L277-L287)

        function claim(uint256 _tokenId) external returns (uint256) {
            if (block.timestamp >=...

Vulnerable code:
function claim(uint256 _tokenId) external returns (uint256) {
if (block.timestamp >= time_cursor) _checkpoint_total_supply();
uint256 _last_token_time = last_token_time;
_last_token_time = _last_token_time / WEEK * WEEK;
uint256 amount = _claim(_tokenId, voting_escrow, _last_token_time);
if (amount != 0) {
@>          IVotingEscrow(voting_escrow).deposit_for(_tokenId, amount);
token_last_balance -= amount;
}
return amount;
}

require(_value > 0); // dev: need non-zero value
require(_locked.amount > 0, "No existing lock found");
@>      require(_locked.end > block.timestamp, "Cannot add to expired lock. Withdraw");
_deposit_for(_tokenId, _value, 0, _locked, DepositType.DEPOSIT_FOR_TYPE);
}

@>      require(_locked.end > block.timestamp, "Lock expired");
require(_locked.amount > 0, "Nothing is locked");
require(unlock_time > _locked.end, "Can only increase lock duration");
require(unlock_time <= block.timestamp + MAXTIME, "Voting lock can be 4 years max");
MEDIUM severity: `PositionManager#liquidatePosition` fails to update vaultDebt and vaultCollateral. **Details**

**First discovered by Dev team during audit period**

[PositionManager.sol#L169-L185](https://github.com/hyperstable/contracts/blob/35db5f2d3c8c1adac30758357fbbcfe55f0144a3/src/core/PositionManager.sol#L169-L185)

        function liquidatePosition(address _vault, address _target,...

Vulnerable code:
function liquidatePosition(address _vault, address _target, uint256 _debtToRepay, uint256 _sharesToLiquidate)
external
{
if (msg.sender != liquidationManager) {
revert OnlyLiquidatorManager();
}
// Debt and collateral shares are adjusted for the liquidated account
_debtSnapshot[_target][_vault] -= _debtToRepay;
collateralShares[_target][_vault] -= _sharesToLiquidate;
MEDIUM severity: Airdrop supply methodology has been changed leading to excess token emissions. **Details**

[MerkleClaim.sol#L48-L69](https://github.com/velodrome-finance/v1/blob/de6b2a19b5174013112ad41f07cf98352bfe1f24/contracts/redeem/MerkleClaim.sol#L48-L69)

        function claim(
            address to,
            uint256 amount,
            bytes32[] calldata proof
        )...

Vulnerable code:
function claim(
address to,
uint256 amount,
bytes32[] calldata proof
) external {
// Throw if address has already claimed tokens
require(!hasClaimed[to], "ALREADY_CLAIMED");

// Verify merkle proof, or revert if not in tree
bytes32 leaf = keccak256(abi.encodePacked(to, amount));
bool isValidLeaf = MerkleProof.verify(proof, merkleRoot, leaf);
require(isValidLeaf, "NOT_IN_MERKLE");

// Emit claim event
emit Claim(to, amount);
}
MEDIUM severity: Curve gauge rewards can be griefed. **Details**

[Gauge.sol#L123-L131](https://github.com/hyperstable/contracts/blob/35db5f2d3c8c1adac30758357fbbcfe55f0144a3/src/governance/Gauge.sol#L123-L131)

        function claimFees() external lock {
    @>      require(msg.sender == IVotingEscrow(_ve).team(), "only team");

            if...

Vulnerable code:
def claim_rewards(_addr: address = msg.sender, _receiver: address = ZERO_ADDRESS):
"""
@notice Claim available reward tokens for _addr
@param _addr Address to claim for
@param _receiver Address to transfer rewards to - if set to
ZERO_ADDRESS, uses the default reward receiver
for the caller
"""
if _receiver != ZERO_ADDRESS:
@>          assert _addr == msg.sender  # dev: cannot redirect when claiming for another user
self._checkpoint_rewards(_addr, self.totalSupply, True, _receiver)
MEDIUM severity: `AdaptiveIRM#_curve` multiples instead of dividing leading to "V" shaped curve instead of expected "L" shaped curve. **Details**

[AdaptiveIRM.sol#L110-L115](https://github.com/hyperstable/contracts/blob/35db5f2d3c8c1adac30758357fbbcfe55f0144a3/src/libraries/AdaptiveIRM.sol#L110-L115)

        function _curve(int256 _rateAtTarget, int256 err) private pure returns (int256) {
            // Non negative because 1...

Vulnerable code:
function _curve(int256 _rateAtTarget, int256 err) private pure returns (int256) {
// Non negative because 1 - 1/C >= 0, C - 1 >= 0.
@>      int256 coeff = err < 0 ? INT_WAD - INT_WAD.sMulWad(CURVE_STEEPNESS) : CURVE_STEEPNESS - INT_WAD;
// Non negative if _rateAtTarget >= 0 because if err < 0, coeff <= 1.
return (coeff.sMulWad(err) + INT_WAD).sMulWad(int256(_rateAtTarget));
}

function _curve(int256 _rateAtTarget, int256 err) private pure returns (int256) {
// Non negative because 1 - 1/C >= 0, C - 1 >= 0.
@>      int256 coeff = err < 0 ? WAD - WAD.wDivToZero(ConstantsLib.CURVE_STEEPNESS) : ConstantsLib.CURVE_STEEPNESS - WAD;
// Non negative if _rateAtTarget >= 0 because if err < 0, coeff <= 1.
return (coeff.wMulToZero(err) + WAD).wMulToZero(int256(_rateAtTarget));
}
MEDIUM severity: `AdaptiveIRM` has been integrated incorrectly and will not work as expected. **Details**

[Morpho.sol#L483-L509](https://github.com/morpho-org/morpho-blue/blob/eb65770e12c4cdae5836c0027e35b9c82794c3eb/src/Morpho.sol#L483-L509)

        function _accrueInterest(MarketParams memory marketParams, Id id) internal {
            uint256 elapsed = block.timestamp -...

Vulnerable code:
function _accrueInterest(MarketParams memory marketParams, Id id) internal {
uint256 elapsed = block.timestamp - market[id].lastUpdate;
if (elapsed == 0) return;

if (marketParams.irm != address(0)) {
@>          uint256 borrowRate = IIrm(marketParams.irm).borrowRate(marketParams, market[id]);
@>          uint256 interest = market[id].totalBorrowAssets.wMulDown(borrowRate.wTaylorCompounded(elapsed));
market[id].totalBorrowAssets += interest.toUint128();
market[id].totalSupplyAssets += interest.toUint128();

uint256 feeShares;
if (market[id].fee != 0) {
uint256 feeAmount = interest.wMulDown(market[id].fee);
// The fee amount is subtracted from the total supply in this calculation to compensate for the fact
// that total supply is already increased by the full interest (including the fee amount).
feeShares =
feeAmount.toSharesDown(market[id].totalSupplyAssets - feeAmount, market[id].totalSupplyShares);
position[id][feeRecipient].supplyShares += feeShares;
market[id].totalSupplyShares += feeShares.toUint128();
}
HIGH severity: Basic validation missing on `mint`and `mintTo`. **Description:** 

Observe that both `mint`and `mintTo`functions are missing basic validation for `to`address,amount/quantity.

**Recommendations:** 

Add below to mint &mintTo function at ERC20Token.sol

\

Add below to mint &mintTo function at ERC721ACollection.sol

\

Vulnerable code:
require(to!=address(0)&&amount>0,""Incorrect params"");

\

require(quantity>0 &&to!=address(0),""Incorrect params"");// for mintTo require(quantity>0,""Incorrect params"");// for mint

\
MEDIUM severity: GDACurve does not validate new spot price. **Description:**
The new spot price calculated in `GDACurve::getBuyInfo` and `GDACurve::getSellInfo` is not currently validated against `MIN_PRICE`, meaning that the price could fall below this value.

While a minimum price check is performed explicitly in `GDACurve::validateSpotPrice`, the same...

Vulnerable code:
GDACurve.sol (Line 81-91)

        // The new spot price is multiplied by alpha^n and divided by the time decay so future
        // calculations do not need to track number of items sold or the initial time/price. This new spot price
        // implicitly stores the initial price, total items sold so far, and time elapsed since the start.
        {
            UD60x18 newSpotPrice_ = spotPrice_.mul(alphaPowN);
            newSpotPrice_ = newSpotPrice_.div(decayFactor);
            if (newSpotPrice_.gt(ud(type(uint128).max))) {
                return (Error.SPOT_PRICE_OVERFLOW, 0, 0, 0, 0, 0);
            } //@audit-info Missing minimum price check
            newSpotPrice = uint128(unwrap(newSpotPrice_));
        }

GDACurve.sol (Line 34-36)

    function validateSpotPrice(uint128 newSpotPrice) external pure override returns (bool) {
        return newSpotPrice >= MIN_PRICE;
    }
HIGH severity: Owner calling `LSSVMPair::changeSpotPrice` can cause arithmetic over/underflows on later swaps. **Description:**
Changing the spot price to a value higher than the current ERC20 (or ETH) balance of the pair can cause unintended reverts in valid swap calls later on.

**Proof of Concept:**

Full proof of concept...

Vulnerable code:
‌// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import {InvariantERC721LinearERC20} from "./InvariantERC721LinearERC20.t.sol";
import {IERC721Mintable} from "../interfaces/IERC721Mintable.sol";

contract SwapArithmeticOverflow is InvariantERC721LinearERC20 {
    function setUp() public override {
        InvariantERC721LinearERC20.setUp();
    }

    function test_OverflowFail() public {
        s_pair.changeSpotPrice(20989589403855433688750111262);

        address payable msgSender = payable(0x0000000000000000000000000000000000004f89);
        changePrank(msgSender);

        uint256 newNFTId = 333;
        IERC721Mintable(address(s_test721)).mint(msgSender, newNFTId);
        (,,, uint256 minOutputAmount,,) = s_pair.getSellNFTQuote(newNFTId, 1);
        s_test721.approve(address(s_pair), newNFTId);
        uint256[] memory nftIds = new uint256[](1);
        nftIds[0] = newNFTId;

        vm.expectRevert("TRANSFER_FAILED");
        uint256 outputAmount = s_pair.swapNFTsForToken(nftIds, minOutputAmount, msgSender, false, address(0));
    }
}
HIGH severity: Unreachable code path in `RoyaltyEngine::_getRoyaltyAndSpec`. Within `RoyaltyEngine`, `int16` values have been copied over from the manifold contract for use as enum values relating to different royalty specifications with `int16 private constant NONE = -1;` and `int16 private constant NOT_CONFIGURED = 0;`. The [if...

Vulnerable code:
if (spec == NONE) {
    return (recipients, amounts, spec, royaltyAddress, addToCache);
}
LOW severity: <a name="GAS-4"></a>[GAS-4] Using bools for storage incurs overhead. Use uint256(1) and uint256(2) for true/false to avoid a Gwarmaccess (100 gas), and to avoid Gsset (20000 gas) when changing from ‘false’ to ‘true’, after having been ‘true’ in the past. See [source](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/58f635312aa21f947cae5f8578638a85aa2519f5/...

Vulnerable code:
File: LSSVMPairFactory.sol

56:     mapping(ICurve => bool) public bondingCurveAllowed;

57:     mapping(address => bool) public override callAllowed;

60:     mapping(address => mapping(address => bool)) public settingsForCollection;
HIGH severity: <a name="GAS-5"></a>[GAS-5] Cache array length outside of loop. If not cached, the solidity compiler will always read the length of the array during each iteration. That is, if it is a storage array, this is an extra sload operation (100 additional extra gas for each iteration except for the first) and if it is a memory array, this is an extra mload operation...

Vulnerable code:
File: LSSVMPair.sol

673:         for (uint256 i; i < calls.length;) {

File: LSSVMPairERC20.sol

68:             for (uint256 i; i < royaltyRecipients.length;) {

93:             for (uint256 i; i < royaltyRecipients.length;) {

File: LSSVMPairETH.sol

57:         for (uint256 i; i < royaltyRecipients.length;) {
HIGH severity: <a name="GAS-7"></a>[GAS-7] Use Custom Errors. [Source](https://blog.soliditylang.org/2021/04/21/custom-errors/)
Instead of using error strings, to reduce deployment and runtime cost, you should use Custom Errors. This would save both deployment and runtime cost.

*Instances (21)*:

Vulnerable code:
File: LSSVMRouter.sol

504:         require(factory.isValidPair(msg.sender), "Not pair");

506:         require(factory.getPairTokenType(msg.sender) == ILSSVMPairFactoryLike.PairTokenType.ERC20, "Not ERC20 pair");

522:         require(factory.isValidPair(msg.sender), "Not pair");

536:         require(factory.isValidPair(msg.sender), "Not pair");

549:         require(block.timestamp <= deadline, "Deadline passed");

578:             require(error == CurveErrorCodes.Error.OK, "Bonding curve error");

658:         require(outputAmount >= minOutput, "outputAmount too low");

File: settings/StandardSettings.sol

45:         require(owner() == address(0), "Initialized");

128:         require(pair.poolType() == ILSSVMPair.PoolType.TRADE, "Only TRADE pairs");

131:         require(pair.fee() <= MAX_SETTABLE_FEE, "Fee too high");

134:         require(msg.value == getSettingsCost(), "Insufficient payment");

144:             revert("Pair verification failed");

178:             require(block.timestamp > pairInfo.unlockTime, "Lockup not over");

180:             revert("Not prev owner or authed");

214:         require(msg.sender == pairInfo.prevOwner, "Not prev owner");

215:         require(newFee <= MAX_SETTABLE_FEE, "Fee too high");

231:         require(msg.sender == pairInfo.prevOwner, "Not prev owner");

309:         revert("Pricing and liquidity mismatch");

File: settings/StandardSettingsFactory.sol

28:         require(royaltyBps <= (BASE / 10), "Max 10% for modified royalty bps");

29:         require(feeSplitBps <= BASE, "Max 100% for trade fee bps split");

30:         require(secDuration <= ONE_YEAR_SECS, "Max lock duration 1 year");
LOW severity: <a name="GAS-9"></a>[GAS-9] Using `private` rather than `public` for constants, saves gas. If needed, the values can be read from the verified contract source code, or if there are multiple values there can be a single getter function that [returns a tuple](https://github.com/code-423n4/2022-08-frax/blob/90f55a9ce4e25bceed3a74290b854341d8de6afa/src/contracts/FraxlendPair.sol#L156-L178)...

Vulnerable code:
File: bonding-curves/ExponentialCurve.sol

15:     uint256 public constant MIN_PRICE = 1000000 wei;

File: bonding-curves/GDACurve.sol

21:     uint256 public constant MIN_PRICE = 1 gwei;
HIGH severity: <a name="GAS-13"></a>[GAS-13] `internal` functions not called by the contract should be removed. If the functions are required by an interface, the contract should inherit from that interface and use the `override` keyword

*Instances (8)*:

Vulnerable code:
File: lib/LSSVMPairCloner.sol

22:     function cloneERC721ETHPair(

112:     function cloneERC721ERC20Pair(

204:     function isERC721ETHPairClone(address factory, address implementation, address query)

238:     function isERC721ERC20PairClone(address factory, address implementation, address query)

274:         address implementation,

361:         ILSSVMPairFactoryLike factory,

450:         returns (bool result)

484:         returns (bool result)
HIGH severity: <a name="N"></a>[NMissing checks for `address(0)` when assigning values to address state variables. *Instances (4)*:

Vulnerable code:
File: LSSVMPairFactory.sol

110:         _caller = _NOT_ENTERED;

349:         _caller = _NOT_ENTERED;

File: lib/OwnableWithTransferCallback.sol

25:         _owner = initialOwner;

71:         _owner = newOwner;
HIGH severity: <a name="N"></a>[NEvent is missing `indexed` fields. Index event fields make the field more quickly accessible to off-chain tools that parse events. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Each event should use three indexed fields if...

Vulnerable code:
File: LSSVMPair.sol

82:     event SwapNFTInPair(uint256 amountIn, uint256[] ids);

83:     event SwapNFTInPair(uint256 amountIn, uint256 numNFTs);

84:     event SwapNFTOutPair(uint256 amountOut, uint256[] ids);

85:     event SwapNFTOutPair(uint256 amountOut, uint256 numNFTs);

86:     event SpotPriceUpdate(uint128 newSpotPrice);

87:     event TokenDeposit(uint256 amount);

88:     event TokenWithdrawal(uint256 amount);

89:     event NFTWithdrawal(uint256[] ids);

90:     event NFTWithdrawal(uint256 numNFTs);

91:     event DeltaUpdate(uint128 newDelta);

92:     event FeeUpdate(uint96 newFee);

File: LSSVMPairFactory.sol

75:     event ERC20Deposit(address indexed poolAddress, uint256 amount);

76:     event NFTDeposit(address indexed poolAddress, uint256[] ids);

77:     event ERC1155Deposit(address indexed poolAddress, uint256 indexed id, uint256 amount);

79:     event ProtocolFeeMultiplierUpdate(uint256 newMultiplier);

80:     event BondingCurveStatusUpdate(ICurve indexed bondingCurve, bool isAllowed);

81:     event CallTargetStatusUpdate(address indexed target, bool isAllowed);

82:     event RouterStatusUpdate(LSSVMRouter indexed router, bool isAllowed);