Aria engaged Guardian to review the security of their Aria's IPRWA contracts. From the 2nd of July to the 9th of July, a team of 5 auditors reviewed the source code in scope.
- Published
- Review window
- July 2 to 9, 2025
- Language
- Solidity
- Chains
- Story
- Sector
- Real-world assets
- 0 Critical
- 4 High
- 6 Medium
- 14 Low
- 3 Informational
Scope
Overview
Aria engaged Guardian to review the security of their Aria's IPRWA contracts. From the 2nd of July to the 9th of July, a team of 5 auditors reviewed the source code in scope.
Findings 27
-
H-01 High Blacklist And License Storage Collisions Logical Error Resolved
Description
Proof of concept: PoC
The
Legalcontract inherits from bothBlacklistandLicensecontracts. However, both inherited contracts use the slot 0 to store data, causing data corruption due to the overwritten storage slot.For example, adding a user to the blacklist will make
licenseVersionvalue equal to theblacklistlength, and vice versa.Recommendation
Make sure the correct storage identifier is used instead of
0x0:- LicenseStorage:
keccak256(abi.encode(uint256(keccak256("aria-protocol.License")) - 1)) &
~bytes32(uint256(0xff));- BlacklistStorage:
keccak256(abi.encode(uint256(keccak256("aria-protocol.Blacklist")) - 1)) &
~bytes32(uint256(0xff)):Resolution
Aria Team: The issue was resolved in PR#80.
- LicenseStorage:
-
H-02 High Inflation Attack In IPRWAStaking Frontrunning Partially resolved
Description
Proof of concept: PoC
The
IPRWAStakingcontract is vulnerable to a share inflation attack, which allows an attacker to manipulate the share-to-token exchange rate and extract a disproportionate share of the staked tokens for first stake. This is particularly severe considering there would be new staking contract each IP, creating this situation of first deposit likely on regular basis.Attack Scenario: Step 1: Attacker Becomes the First Depositor
The attacker ensures they are the first to stake:
- Contract initial state
Step 2: Attacker Manipulates the Exchange Rate
The attacker artificially inflates the ratio by donating tokens directly to the contract:
- New state
- New exchange rate
Step 3: Victim Gets Massively Diluted
Now, a victim stakes a large amount, say 100 IPRWA:
stIPRWAminted to victim- The victim receives 0
stIPRWAfor staking 100 IPRWA, due to rounding down. No checks are in place to prevent zero minting.
Step 4: Attacker Unstakes and Profits
The attacker now unstakes their 1 wei
stIPRWA:- Unstaked amount:
- Attacker receives almost 1100 IPRWA, effectively stealing the victim’s entire deposit.
Additionally, any IPRWA deposit to the staking contract when
stIPRWAsupply is zero, either maliciously (donations) or inadvertently (depositing royalties), will cause the numerator of_stIPRWAPerIPRWAcalculation to be 0, while the denominator is non zero. Therefore, any subsequent stakes will mint zerostIPRWAtokens.Recommendation
To defend against this class of attacks:
- Option 1: Consider performing an initial seed deposit during or immediately after deployment to set a minimum viable exchange rate.
- Option 2: Consider using a virtual offset as proposed in this ERC-4626 article to smooth out early ratio manipulation.
Resolution
Aria Team: The issue was resolved in PR#100.
-
H-03 High Blacklist Bypass Via Transfer Validation Resolved
Description
Aria implements a blacklist mechanism to prevent malicious actors from staking
IPRWAor unstakingsIPRWA. However, this check is only enforced at the staking/unstaking functions and not at the token level.Since the
IPRWAandsIPRWAtoken contracts themselves do not enforce blacklist restrictions on transfers, a blacklisted user can simply transfer their tokens to another address to bypass these controls.Example: If Alice is blacklisted, she can transfer her
sIPRWAtokens to another wallet she controls and still successfully unstake from that new address.Recommendation
Extend the blacklist logic to token transfers by introducing a
beforeTransferhook that checks the blacklist for both sender and receiver addresses.Resolution
Aria Team: The issue was resolved in PR#80.
-
H-04 High Stake() Susceptible To Griefing DoS Resolved
Description
In the
stake()function, Aria calculates_stIPRWAPerIPRWAusing the following logic:UD60x18 numerator = scaledStakedIPRWATotalSupply.sub(scaledStakedIPRWABalance);This formula subtracts the contract’s own
stIPRWAbalance from the total supply, presumably to account for protocol-heldstIPRWAused in royalty distributions.However, this opens up a griefing vector:
- An attacker can stake IPRWA to receive
stIPRWA, then donate those tokens to the staking contract’s own
address.
- This artificially inflates the
scaledStakedIPRWABalance, eventually making it equal to the total supply. - When this happens, the numerator becomes zero, causing
_stIPRWAPerIPRWAto evaluate to zero. - As a result, subsequent users attempting to stake will receive zero
stIPRWA, effectively locking their IPRWA
with no yield or liquidity — bricking the vault.
While Aria's rationale for this setup is to allow royalty distributions via protocol-held
stIPRWA, this mechanism is problematic. OncestIPRWAis sent to the contract address, it cannot re-enter circulation cleanly:- Theoretically, an admin could call
withdraw()to recover thestIPRWA, but this would reduce the per-token
rate, effectively penalizing existing stakers.
- Thus, the system introduces irreversible accounting imbalances and risks permanent vault malfunction.
Recommendation
Avoid factoring in
scaledStakedIPRWABalancewhen computing ratios in both thestake()andunstake()functions. Consider not usingsIPRWAfor royalties.Resolution
Aria Team: The issue was resolved in PR#81.
- An attacker can stake IPRWA to receive
-
M-01 Medium Incorrect Fractional Token Supply Check Validation Resolved
Description
The
_deployFractionalTokenfunction comparesfractionalTokenTotalSupplywith thescaledTotalDepositsvalue before deploying the fractional token.However, the
_getScaledTotalDepositsfunction only includes deposits associated with the latest USDC address and excludes previous deposits if there is more than one USDC address, causing the check to be performed with incorrect values.Recommendation
Use the entire deposit amount by iterating over all USDC addresses, similar to how the
_fundraiseCalculateClaimfunction does in theVaultFundraisecontract.Resolution
Aria Team: Resolved
-
M-02 Medium Faulty Pause Role Logic Access Control Resolved
Description
Aria intends to allow either
PAUSABLE_ROLEholders orDEFAULT_ADMIN_ROLEholders to modify the pause state of the protocol.However, due to the use of logical OR with negated conditions, the current implementation allows only those who hold both roles to execute the function successfully.
Problematic line
if (hasRole(PAUSABLE_ROLE, msg.sender) || hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) revert Unauthorized();Example
If Alice holds only
PAUSABLE_ROLE, then:● hasRole(PAUSABLE_ROLE, msg.sender) →false● hasRole(DEFAULT_ADMIN_ROLE, msg.sender) →true- The OR condition (false || true) → true → reverts
Recommendation
Update the logic to check that the caller holds at least one of the roles correctly.
Resolution
Aria Team: The issue was resolved in PR#76.
-
M-03 Medium Ineffective License Enforcement Validation Resolved
Description
Aria introduces a license-signing mechanism that allows users to sign licenses via
signLicense(). Additionally, admins can revoke licenses from users by callingrevokeSignature(). However, this system has enforcement gaps:- Reuse of Signatures: A user whose license has been revoked can still reuse their old signature to
sign the license and unstake tokens, as there's no mechanism invalidating the original signed payload.
- Bypassing License Enforcement via Transfer: Even if a user's license is revoked, they can transfer
their
sIPRWAto another address (e.g., via a swap in a public pool likesIPRWA:IPRWA) because thebeforeTransferhook ofsIPRWAdoes not enforce any license-related checks. This allows the receiver—who may not have signed the current license—to exit without needing to sign again.- License Upgrades Ignored: If an IPRWA issuer upgrades the license (changes the license version or
URI), existing
sIPRWAholders who signed the older license can bypass the need to re-sign the updated license. They can simply swap their tokens in public pools to exit, which again defeats the license enforcement.Recommendation
- Invalidate Old Signatures: Implement nonce-based replay protection to invalidate previously signed
payloads after a license is revoked.
- Enforce License Validation on Transfer: Add a
beforeTransferhook in thesIPRWAtoken contract
that verifies whether the sender and receiver have signed the current license version. Note that if this is done, it would cause reverts with DeFi pools, since they do not support signing, in that case a explicit skip list for validations would need to be maintained by admin.
Resolution
Aria Team: The issue was resolved in PR#83.
-
M-04 Medium Permissionless Vault Creation Validation Resolved
Description
The
deployFundraiseIpVaultanddeployWhitelistIpVaultfunctions in the factory contract are permissionless and can result in illegitimate vaults being presented as Aria vaults, potentially tricking users through malicious deployments.Additionally, whitelist vault initializations require a Merkle root, and generating this root requires the vault address. This means deployers must calculate the address of the vault to be deployed.
However, since vault creation is permissionless, frontrunning and creating another vault from factory changes the predicted address of the whitelist vault. As a result, the Merkle root becomes invalid.
Recommendation
Restrict vault deployments to admins only.
Resolution
Aria Team: The issue was resolved in PR#82.
-
M-05 Medium Incorrect Tracking Of usersNetIPRWADeposited DoS Resolved
Description
Proof of concept: PoC
The staking contract tracks deposited amounts using the public
usersNetIPRWADepositedvariable. This value increases when users stake and decreases proportionally when they unstake. However, it does not accurately reflect the actual staked amounts, and it can be manipulated.When the asset-to-share ratio is not 1:1, a user can unstake and then immediately stake again to increase the
usersNetIPRWADepositedvalue, since unstaking removes less principal while staking adds the full amount.Currently, that value is not used beyond being a public variable. However, the impact could be more significant if Aria itself, or other protocols integrating with the Aria staking contracts, rely on
usersNetIPRWADepositedfor their operations.Recommendation
Be aware of this behavior and document it. Alternatively, consider removing the
usersNetIPRWADepositedvariable if it is not planned to be used.Resolution
Aria Team: The issue was resolved in PR#99.
-
M-06 Medium Sandwich Attack Royalties Gaming Partially resolved
Description
Proof of concept: PoC
When users unstake their shares from the
IPRWAStaking, the amount to withdraw is calculated by the_getIPRWAValue. This will calculate theIPRWA:stIPRWAto convert thestIPRWAtokens burned toIPRWA.However, this rate is based on the token balance of the staking contract. This will cause the rate to have a stepwise jump when royalties are deposited.
Malicious users can monitor these royalties deposits, and sandwich the transaction by staking and unstaking, before and after the
depositRoyaltiescall, profiting from the royalties that should have been distributed to existing users.Recommendation
Consider rate based logic or a delayed distribution system, that will prevent royalties to be instantly claimed and avoid step wise jumps. Alternatively, increase the frequency of royalty deposits, to reduce the profit for attackers and make it less likely.
Please be cautious of DEX pools while designing this, as Aria expects to have pools for
sIPRWA/IPRWAandIPRWA/USDC. Depending on how royalties are handled, this could create instant arbitrage opportunities on the DEX.If you decide to go with a rate-based or delayed royalty distribution model, consider creating a wrapped
sIPRWAspecifically for use in DeFi pools.Resolution
Aria Team: Partially Resolved.
-
L-01 Low Signature-Based Mapping Vulnerability Validation Resolved
Description
Aria uses the signature itself as the key in the mapping:
signatures[msg.sender] = signature;However, be aware that for the same digest, multiple valid signatures can exist. This allows a user to replay their signature using the same digest but with different signature bytes.
This bypasses the
License_AlreadySignedcheck and emits theLicenseSignedevent unnecessarily, which could confuse integrators or UIs.While there is no direct incentive to do this—since the function is gated by msg.sender—we wanted to flag this behavior for awareness.
Recommendation
Consider using a mapping like
signed[userAddress] = digestinstead.This would ensure that new signatures are only accepted whensigned[userAddress] ≠ digest.Resolution
Aria Team: The issue was resolved in PR#83.
-
L-02 Low Smart Wallets Cannot Stake DoS Resolved
Description
Aria’s license system requires users to sign a license in order to stake or unstake. However, the current signature verification logic implemented by Aria does not support smart contract signatures (
EIP-1271).As a result, smart contract wallets are unable to stake or unstake via the IPRWA staking contract.
Recommendation
Consider supporting smart contract signatures by implementing
EIP-1271verification.Resolution
Aria Team: The issue was resolved in PR#98.
-
L-03 Low Lack Of Slippage Controls Validation Resolved
Description
The
IPRWAStakingcontract implements stake and unstake functionalities but currently lacks slippage controls.Slippage controls can be desirable to protect users against inflation-based attacks or to give them more control over the expected return value during staking or unstaking.
Recommendation
Consider adding an optional
minOutparameter to both stake and unstake functions to allow users to specify a minimum acceptable return and revert the transaction if the actual amount falls below it.Resolution
Aria Team: The issue was resolved in PR#95.
-
L-04 Low Front-Running And Value Leakage Frontrunning Acknowledged
Description
Aria expects to receive royalties in USDC, which are later converted into IPRWA and deposited into the staking contract as rewards. However, this approach poses a few potential issues:
- Front-running risk due to predictable swap flow
As we understand, the expected royalty flow is:
- Onramp: Royalties arrive in IP
- Coinbase: IP is swapped to USDC
- Offramp: USDC is transferred to Story (
RWAKfeller’s ledger) - Story: USDC is swapped to IPRWA on PiperX
The problem begins from the offramp stage onward, which is publicly observable. Once USDC reaches the Story address, any external actor can anticipate the swap and front-run it by executing a USDC → IPRWA trade in the IPRWA/USDC pool. They profit from the price movement induced by Aria’s expected buy, effectively sandwiching the trade. This causes Aria to acquire IPRWA at a worse rate, thereby diluting the yield meant for stakers — a subtle form of MEV extraction.
- Royalty value leakage to non-stakers
Since the swap is done on the open market (IPRWA/USDC pool), the resulting price impact benefits all IPRWA holders, not just stakers. Thus, a portion of the royalty value leaks to non-staking holders, reducing the effective yield for those who have actually staked.
Recommendation
To mitigate these risks:
- Perform swaps in randomized, smaller tranches without a predictable schedule.
- Use fresh recipient addresses for each offramp to obscure tracking.
- If the royalty amount is large relative to on-chain liquidity, split it across multiple fresh addresses and execute the swaps from them independently.
- For extreme cases with low liquidity and large royalty anticipation, consider introducing a beforeTransfer hook in the IPRWA token contract. Aria can:
- Temporarily pause transfers by setting a
allowTransfers = falseflag, - Enable swaps by toggling
allowTransfers = truewithin a dedicated smart contract, execute the swap, and then re-disable transfers.
Resolution
Aria Team: Acknowledged.
-
L-05 Low Arbitrage Risk From Royalty Deposits Frontrunning Acknowledged
Description
Aria expects to maintain a DEX pool with the token pair
sIPRWA/IPRWA. However, each time royalties are deposited into the staking contract, the vault value backingsIPRWAincreases relative toIPRWA.This creates an arbitrage opportunity in the DEX pool:
The price of
sIPRWAlags behind its new intrinsic value post-deposit, allowing external actors to profit from the mismatch — potentially at the expense of the protocol or its users.Recommendation
Be aware of this arbitrage vector. Since Aria controls the royalty deposit process, it can easily capture this value internally using a atomic multicall:
- Swap USDC to IPRWA
- Deposit IPRWA as royalties into the staking contract
- Swap IPRWA to
sIPRWAin the DEX pool, to reflect the updated vault value
This approach prevents external actors from frontrunning the arbitrage opportunity and ensures the value created from royalty
Resolution
Aria Team: Acknowledged.
-
L-06 Low Claims DoS'ed By Admin Fractional Minting Validation Resolved
Description
Proof of concept: PoC
Fractional tokens are based on
ERC20CappedUpgradeable, and the cap is set tofractionalTokenTotalSupplyat the time of registration in the_deployFractionalTokenfunction.After an IP is fractionalized, users can claim their fractional tokens in proportion to their individual deposit amounts relative to the total deposits. The cap, defined by
fractionalTokenTotalSupply, is reached once all users have claimed their tokens.There is an additional fractional token minting mechanism initiated by the admin, which can be executed by anyone after a timelock period. This process involves the
initFractionalTokenMintandexecFractionalTokenMintfunctions and allows the remaining tokens to be minted to a specified address.However, the
initFractionalTokenMintfunction does not include a check to ensure that theclaimDeadlinehas passed and that all user claims have been completed.The
initFractionalTokenMintfunction can be called while user claims are still ongoing, and the_getAdjustedMintAmountfunction incorrectly returns a higher mintable amount, as it only compares the current supply against the cap.This results in later users being unable to claim their fractional tokens due to the cap being reached, effectively causing them to lose their funds. Additionally, although the function is restricted to the admin, the admin does not have to be malicious and may simply be unaware of this behavior.
Recommendation
The
initFractionalTokenMintfunction should check theclaimDeadlineand only be callable after user claims have been completed.Resolution
Aria Team: The issue was resolved in PR#91.
-
L-07 Low Warning Regarding Story Registration Fee Warning Resolved
Description
During the registration and fractionalization process, the
mintAndRegisterIpAndAttachPILTermsAndDistributeRoyaltyTokensfunction of theRoyaltyTokenDistributionWorkflowsperiphery contract is called.This contract handles the registration of the IP asset on the Story chain. The
RoyaltyTokenDistributionWorkflowscontract calls theIPRegistry.registerfunction, and theregisterFeePayeris msg.sender during this call.This means the periphery contract is responsible for paying the registration fee if
feeAmountis greater than zero. There isn’t an issue at the moment, as the registration fee is set to zero on live contracts.However, if the Story Protocol decides to increase the fee, the
RoyaltyTokenDistributionWorkflowscontract will be responsible for paying it. This would likely require the fee tokens to be transferred from the Aria vault to the periphery contract during the registration process.Recommendation
Be aware of this situation. Since Aria vaults are also upgradeable, they can be modified to align with changes in the Story Protocol’s behavior.
Resolution
Aria Team: The issue was resolved in PR#86.
-
L-08 Low Missing IPAccount Execute Functionality Informational Resolved
Description
The IP asset NFT is held in the vault, and each IP asset has an associated IP account. These IP accounts are bound to the IP asset, and the NFT owner is also the owner of the corresponding IP account.
IP accounts need to be utilized, using their
executeandexecuteWithSigfunctions, in order to interact with the Story Protocol's modules. However, the vault has no way to interact with its own IP account.Recommendation
Consider implementing a similar execute function that allows the vault to interact with its IP account in order to fully utilize all features of the Story Protocol. Alternatively, if this limitation is intentional, it should be clearly documented.
Resolution
Aria Team: The issue was resolved in PR#96.
-
L-09 Low Fundraise Closed With No Expiration Time Check Validation Resolved
Description
The
VaultStateCheckerlibrary is in charge of updating the vault state toClosedif the expiration time is reached. However, admin can close the fundraise without checking this timestamp, creating inconsistencies between the library.Recommendation
If this is intended behavior, consider documenting it for users, so they are aware admin can close the fundraise at any time. Alternatively, validate if the expiration time is reached in
closeRaiseadmin function.Resolution
Aria Team: The issue was resolved in PR#90.
-
L-10 Low Failed Withdrawals Due To Previous Withdraw Informational Resolved
Description
The vault contract includes both
withdraw()andwithdraw(address token)functions. Thewithdraw()function iterates through all USDC token addresses and transfers the entire deposited amounts. Thewithdraw(address token)function transfers the deposited amount for the specified token.However, if the
withdraw(address token)function is called once, the regularwithdraw()function can no longer be used for the remaining USDC addresses. This is because the iteration will revert due to insufficient balance when it reaches the token address that was already withdrawn.Recommendation
Document this behavior for vault admins. They should either use the regular
withdrawfunction exclusively, or call thewithdraw(address token)function separately for each token address.Resolution
Aria Team: The issue was resolved in PR#103.
-
L-11 Low Merkle Root Updates After Claim Logical Error Resolved
Description
Whitelisted users can claim their fractionalized tokens using Merkle proofs, and each user can only claim once. However, the vault admin can update the Merkle root at any time, regardless of whether the previous root was used for claims.
If a user has already claimed their tokens with the old root but is allocated a higher amount in the new root, they will be unable to claim the difference because
fractionalTokenClaimedremains true for their account, resulting in a loss of tokens.Conversely, if a user claimed based on the previous root but has a much lower allocation in the new root, this could cause the overall cap to be reached unexpectedly.
Recommendation
One option to consider is setting a claim start time, allowing the admin to verify everything is correct before claims begin and preventing Merkle root updates once claiming has started. Alternatively add a check in the
setMerkleRootand allow only if the token has not been fractionalized yet.Resolution
Aria Team: The issue was resolved in PR#89.
-
L-12 Low Whitelist Claims DoS'ed Configuration Resolved
Description
During
claimFractionalTokensfor whitelist vaults, the same_USDC_WHITELISTaddress will be used andfractionalTokenClaimed[usdc][claimer]will be set to true. In case the same claimer address is present in different leaves, the user will only be able to claim one time.Recommendation
Consider verifying the merkle tree does not contain more than one leaf with the same user address.
Resolution
Aria Team: The issue was resolved in PR#88.
-
L-13 Low recoverLostTokens Blocked By Stale totalDeposits Logical Error Resolved
Description
The
recoverLostTokensfunction is prevented from withdrawing the deposited USDC tokens from users.However if the vault closed and the admin withdraws all of these deposited USDC tokens the
totalDepositsvariable is not reset to 0 as it is later used for the share price calculation in the claim flow. This blocks therecoverLostTokensfunction from legitimate actions.Recommendation
Do not decrease the total deposited USDC value from the recoverable amount if the admin already withdraw the funds.
Resolution
Aria Team: The issue was resolved in PR#103.
-
L-14 Low Blacklisted Tokens Permanently Locked Warning Resolved
Description
The protocol has a blacklist feature, however once tokens are blacklisted there is no way for the admin to seize those assets, effectively locking them in perpetuity.
Recommendation
Consider adding an option for the admin to seize blacklisted assets.
Resolution
Aria Team: The issue was resolved in PR#80.
-
I-01 Informational Unused Code Superfluous Code Resolved
Description
The error
IPRWAStaking.IncorrectSignatureLengthis never used.Recommendation
Remove unused error.
Resolution
Aria Team: The issue was resolved in PR#93.
-
I-02 Informational Incorrect Natspec Documentation Resolved
Description
IAriaIPRWAVaultFactory.deployFundraiseIpVaultandIAriaIPRWAVaultFactory.deployWhitelistIpVaulthave awithdrawalTimelockDurationbut this refers to a previous feature.VaultFundraiseAdmin.withdraw()missing natspec.
Recommendation
Fix the natspec for the function above.
Resolution
Aria Team: The issue was resolved in PR#92.
-
I-03 Informational Whitelist Vault Claims Can Fail Configuration Resolved
Description
Extra attention should be made before calling the
registerIPAndFractionalizeon a whitelist vault, as once the fractional token is deployed, the total supply is fixed.If there is any inconsistency with the total claim amounts in the merkle tree, users will be DoS'ed when claiming their IPRWA tokens.
This is different from the fundraise vault, as the token deployment will fail if the supply is not above the scaled total deposits.
Recommendation
Add a warning documentation to the
registerIPAndFractionalizeto verify the total amounts to claim in merkle tree before deploying the fractional token.Resolution
Aria Team: The issue was resolved in PR#94.
No findings match.
Invariants 19
The review's fuzzing suite asserted 19 invariants. 8 held and 11 did not.
Every invariant tested
| ID | Invariant | Result |
|---|---|---|
ARIA-01 | Redeemable IPRWA should be equal to the IPRWA balance of the staking contract | Broken |
VAULT-01 | Whitelist proofs validate correctly | Held |
VAULT-02 | Fundraise fractional token balance should increase on successful claim | Held |
VAULT-03 | Whitelist fractional token balance increase should match claim amount | Held |
STAKE-01 | stIPRWA:IPRWA ratio calculations are consistent | Broken |
STAKE-02 | Total staked amount = usersNetIPRWADeposited | Broken |
STAKE-03 | Stake/Unstake operations preserve token conservation | Held |
STAKE-04 | Stake/Unstake operation should not succeed despite actor being blacklisted | Held |
STAKE-05 | Staking ratios are inverse of each other | Broken |
STAKE-06 | User stIPRWA balance changes match stake/unstake amounts | Broken |
STAKE-07 | The value that the iprwaPerStIPRWA() function returns should strictly increase | Broken |
STAKE-08 | never decrease The total amount of IPRWA tokens deposited should always equal | Broken |
STAKE-09 | IPRWAStaking.usersNetIPRWADeposited Revert reason should never be a under or overflow” | Held |
STAKE-10 | Users should always receive > 0 staking tokens after calling stake | Broken |
STAKE-11 | Users should always receive > 0 IPRWA tokens after calling unstake | Broken |
TRANSFER-01 | Transfer should not succeed if sender is blacklisted | Broken |
GUIDED-01 | Stake-Unstake round-trips should be neutral unless royalties are deposited | Broken |
GUIDED-02 | Users receive royalties proportional to their stake percentage | Held |
GUIDED-03 | Late joiners cannot claim royalties for periods they weren't staking | Held |
More from Aria
Put your code through the same review.
This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.
