#43705 sc critical attackers can exploit lack of validation in byc coin issuance pro
Was this helpful?
Was this helpful?
Submitted on Apr 10th 2025 at 07:33:14 UTC by @perseverance for
Report ID: #43705
Report Type: Smart Contract
Report severity: Critical
Target: https://github.com/immunefi-team/CircuitDAO-IoP/tree/main/circuit_puzzles
Impacts:
Protocol insolvency
Permanent significant depeg of stablecoin (BYC), e.g. by forcing undercollateralization
The BYC coin issuance process in the Circuit DAO protocol allows users to borrow BYC coins while providing collateral. However, there is a critical vulnerability in the validation process that could allow attackers to exploit Lack of Validation of amount
in byc_issuing_coin_info
BYC Coin Issuance Process to Issue arbitrary amount of BYC Coin.
This attack can also depeg BYC because BYC will be under collaterized.
In the case of BYC Issuance, the delta
is 0. (please note delta
is extra_delta
mentioned in docs: https://chialisp.com/cats/ ).
This is correct according to the design and explanation of Circuit DAO team explanation.
The flow of code is as below:
So when a user want to borrow BYC, he create a Vault and deposit XCH into the Vault as Collateral. The puzzle will call the vault_borrow with some input parameters.
Here we focus on 2 input parameters:
borrow_amount : The amount user want to borrow
byc_issuing_coin_info : as commented is the BYC issuing coin information : parent_id amount inner_puzzle_hash . Please note that amount is the amount of BYC that was issued
https://github.com/immunefi-team/CircuitDAO-IoP/blob/d2c3171f08864c29fdd436e25a39c95b371df860/circuit_puzzles/programs/vault_borrow.clsp#L1-L20
The Vault coin will verify the borrow_amount that should be backed by enough collateral and the ratio is lower than the configured LTV (Loan to Value) ratio. After the verification done, the Vault will send the message to issue the BYC as below
https://github.com/circuitdao/puzzles/blob/ad9df3df71048c96b7511fd1ec20b1b41c1b5b88/circuit_puzzles/programs/vault_borrow.clsp#L69-L75
https://github.com/circuitdao/puzzles/blob/ad9df3df71048c96b7511fd1ec20b1b41c1b5b88/circuit_puzzles/programs/vault_borrow.clsp#L48-L57
So the byc_issuing_coin_id is important that only that BYC coin can receive the message. It is important to prevent unauthorized issuing of the BYC.
Now as commented above by the CircuitDAO team, the BYC can be issued by anyone. But to spend the BYC, he need to reveal the tail that means run the tail.
https://github.com/immunefi-team/CircuitDAO-IoP/blob/d2c3171f08864c29fdd436e25a39c95b371df860/circuit_puzzles/byc_tail.clsp#L1-L20
And in this tail coin, the message is received or consumed.
https://github.com/immunefi-team/CircuitDAO-IoP/blob/d2c3171f08864c29fdd436e25a39c95b371df860/circuit_puzzles/byc_tail.clsp#L62-L73
So if the Tail coin run succesfully, means spent, then the BYC can be sent to the user and he can own the BYC and use as a stable coin with value of 1 USD.
I notice the vulnerability exists here is that the amount
in byc_issuing_coin_info
is not verified in the coin Vault_borrow coin.
In the vault_borrow, there is only verification against the borrow_amount
.
In the byc_tail.clsp
, the amount
is also not verified against the new_byc_coin_amount
.
So this bug enables the attacker to execute following attack in the POC section below.
Bug Severity: Critical
Impact category:
Protocol insolvency
Permanent significant depeg of stablecoin (BYC), e.g. by forcing undercollateralization
Because the attacker can issue arbitrary amount of BYC .
Likelihood: High
No special privileges required
it is profittable so the likelyhood is high
As explained in the report above.
Step 1: For example, using XCH to issue 10_000_000_000 BYC. This number 10_000_000_000 can be any number.
According to the comment from Circuit DAO team, this can be done by anyone.
Step 2: Attacker create a Vault and deposit 1 XCH and borrow 1 BYC. This is valid because 1 XCH is 10.4 USD and he borrow only 1 BYC.
The attacker input the byc_issuing_coin_info
with valid parent_id
So the vault_borrow
will send the message of with borrow_amount of 1 to the BYC coin.
Step 3: The attacker reveal the tail and send the BYC to his address
In the byc_tail
the check for message will pass.
So the whole process will run succesfully.
The below mermaid and attached sequence diagram (generated from mermaid) helps to illustrate this bug.