Admin can’t burn tokens from either revoked KYC addresses or KYC addresses added to sanction list due to a check in _beforeTokenTransfer #314
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-32
🤖_26_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/rOUSG.sol#L624
Vulnerability details
Impact
The current implementation of the
burn
function in the rOUSG contract restricts the ability of the admin with theBURNER_ROLE
to burn tokens from addresses that have either been removed from the KYC list (KYCRegistry::removeKYCAddresses
) or added to the external chainalysis's sanction list. This is because the_beforeTokenTransfer
function enforces KYC checks for all token transfer operations, including burning tokens. As a result, if an address is no longer KYC-approved or has been sanctioned, theburn
function will fail to execute, preventing the admin from burning tokens as intended. This limitation can hinder essential operations, affecting the integrity and functionality of the protocol.Proof of Concept
Let’s check the
burn
function which calls the internal_burnShares
function (see line 632) :As can be seen in
_burnShares
function it calls_beforeTokenTransfer
in line 560 with the account that we want to burn tokens form. Here is the code of_beforeTokenTransfer
:The
_beforeTokenTransfer
function enforces KYC checks for all token transfers. if we see code block in L597-L600 we can see the require statement that lock the ability of burning token from account that has false in its KYC status, since this function is also used when unwrap rOUSG it is very acceptable in its nature. However, theburn
function should not incorporate these checks. As a result, the admin with theBURNER_ROLE
cannot burn tokens from addresses that are no longer KYC-approved or have been added to the sanctions list.If we dig deeper to see more about
_getKYCStatus
which is part ofKYCRegistryClientUpgradeable
contract:We can tell that the state of the KYC is managed by separate roles in a separate contract and can be revoked at any given moment either by:
Address has been added to sanctions list where it checked in KYCRegistry#L134:
!sanctionsList.isSanctioned
Address is revoked when utilizing
KYCRegistry::removeKYCAddresses
by another role:Thus, This inconsistency in enforcing KYC requirements hinders the admin's ability to perform critical token burning operations, impacting the overall functionality of the protocol.
Similar findings
Tools Used
Recommended Mitigation Steps
Consider these analyzings before solving the issue
If the burn function will be used only by the admin; consider burning shares without checking the KYC status of the address we are burning from. But be caution here as we can not make changes to
_burnShares
function since it used in unwrap! perhaps another enforced burn shares function can do the job.If the burn function would be use by another contracts as of a tokenomics features like the one used by
ousgInstantManager
andOUSG
token, then add another burn function that would be used only by the admin and enforce the burn regardless of the the KYC status of the address we are burning from.Assessed type
Error
The text was updated successfully, but these errors were encountered: