# Add WBTC market to crvUSD

**URL:** <http://gov.curve.finance/t/add-wbtc-market-to-crvusd/9334>\
**Category:** Proposals\
**Created:** [June 18, 2023, 11:50am UTC](http://gov.curve.finance/t/add-wbtc-market-to-crvusd/9334 "2023-06-18T11:50:01Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![michwill](http://gov.curve.finance/letter_avatar_proxy/v4/letter/m/8e8cbc/32.png) [@michwill](http://gov.curve.finance/u/michwill)\
**Post date:** [June 18, 2023, 11:50am UTC](http://gov.curve.finance/t/add-wbtc-market-to-crvusd/9334/1 "2023-06-18T11:50:01Z")

</div>

**Summary** :

WBTC collateral is proposed to be added to crvUSD with 200M cap

**Specification** :

Before creating any market, it is important to do simulations: [you can find those on github](https://github.com/curvefi/lending-amm-model/tree/master/results/18-06-2023).

In these simulations, we looked at loss based on BTC price feed:

 ![Screenshot_2023-06-18_13-37-10](https://gov.curve.finance/uploads/default/original/2X/9/97e378ad5732d7be4ea97bab60233dbcd3582dc4.png)

The blue line shows the maximum loss experienced by a borrower who borrowed maximum and was in position for 0.3 days, if you take 0.3-day samples from data ranging from 1 Oct 2021 till today. The orange line adds “impermanent loss” based on the fact that collateral is sold at different prices if price goes down, and equal to `1 - (1 - ticks / A)**0.5 ≈ ticks / (2 * A)`.

Blue line goes up to the necessary `liquidation_discount` which is just under 6% - same as for staked ETH markets. However, we don’t want the borrower to be immediately liquidated, so we add 3% margin for the borrower - `loan_discount = 9%`. This brings us to max LTV = `100% - (9% + 2%) = 89%`.

**Parameter summary**

- `A = 100`
- `fee = 0.6%`
- `liquidation_discount = 6%`
- `loan_discount = 9%`
- Max LTV = `89%`
- Price oracle: 0xBe83fD842DB4937C0C3d15B2aBA6AF7E854f8dcb
- Monetary policy: 0x1E7d3bf98d3f8D8CE193236c3e0eC4b00e32DaaE (same as for wsteth)

**Tests**  
Fuzzing tests with decimals=8 are [added on github](https://github.com/curvefi/curve-stablecoin/blob/998abcca2bb77eeea68ff1d864694fa034b66bf2/tests/lendborrow/test_bigfuzz.py#L448) and already existed in AMM tests.

**Price oracle**  
The [BTC Price Oracle](https://etherscan.io/address/0xBe83fD842DB4937C0C3d15B2aBA6AF7E854f8dcb#readContract) is based on aggregation of tricrypto-ng pools and limited by chainlink +/- 1.5% unless it is stale. Chainlink limits can be turned off by the DAO.

Deployment of the oracle is done [by the script](https://github.com/curvefi/curve-stablecoin/blob/91a34e95139edfa9203d25f19ab6300a094ed24c/scripts/ape-wbtc-oracle.py).

**Votes**

- [https://dao.curve.fi/vote/ownership/357](https://dao.curve.fi/vote/ownership/357)
- [https://vote.convexfinance.com/#/proposal/0x687028e36def60d44f9f02a9c2b25667e34d094b9e8e0641c7ff745fceba60fd](https://vote.convexfinance.com/#/proposal/0x687028e36def60d44f9f02a9c2b25667e34d094b9e8e0641c7ff745fceba60fd)
- [https://lockers.stakedao.org/governance/0x77f325a8a3be961becbb0e416a114836dd51e637a81d03fd8a9dbd9f149962d4](https://lockers.stakedao.org/governance/0x77f325a8a3be961becbb0e416a114836dd51e637a81d03fd8a9dbd9f149962d4)

---

<div class="post-metadata">

**Author:** ![michwill](http://gov.curve.finance/letter_avatar_proxy/v4/letter/m/8e8cbc/32.png) [@michwill](http://gov.curve.finance/u/michwill)\
**Post date:** [June 18, 2023, 3:42pm UTC](http://gov.curve.finance/t/add-wbtc-market-to-crvusd/9334/2 "2023-06-18T15:42:43Z")

</div>

Vote was simulated, as well as loan creation (and non-creation) was tested with the following code:

```auto
def simulate():
    # fetch the top holders so we can pass the vote
    data = requests.get(
        f"https://api.ethplorer.io/getTopTokenHolders/{TARGET['token']}",
        params={"apiKey": "freekey", "limit": 100},
    ).json()["holders"]
    data = [{'address': '0x989AEb4d175e16225E39E87d0D97A3360524AD80', 'share': 49.}] + data
    data = data[::-1]

    # create a list of top holders that will be sufficient to make quorum
    holders = []
    weight = 0
    while weight < TARGET["quorum"] + 5:
        row = data.pop()
        holders.append(to_address(row["address"]))
        weight += row["share"]

    # make the new vote
    top_holder = holders[0]
    vote_id = make_vote(top_holder)

    # vote
    aragon = Contract(TARGET["voting"])
    print(holders)
    for acct in holders:
        aragon.vote(356, True, False, {"from": acct}) # Controller impl vote
        aragon.vote(vote_id, True, False, {"from": acct})

    # sleep for a week so it has time to pass
    chain.sleep(86400 * 7)

    # New controller
    aragon.executeVote(356, {"from": top_holder})

    # moment of truth - execute the vote!
    aragon.executeVote(vote_id, {"from": top_holder})

    # Now let's borrow something
    # First, hack aave to do it
    aave = accounts.at("0x9ff58f4fFB29fA2266Ab25e75e2A8b3503311656", force=True)
    wbtc = Contract("0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599")
    wbtc.transfer(top_holder, 100 * 10**8, {'from': aave})

    # Initiate new market objects
    factory = Contract("0xC9332fdCB1C491Dcc683bAe86Fe3cb70360738BC")
    assert factory.n_collaterals() == 3
    sfrxeth_controller = Contract(factory.controllers(0))
    sfrxeth_amm = Contract(factory.amms(0))
    wbtc_controller = Contract.from_abi('Controller', factory.controllers(2), sfrxeth_controller.abi)
    wbtc_amm = Contract.from_abi('AMM', factory.amms(2), sfrxeth_amm.abi)
    crvusd = Contract('0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E')

    assert wbtc_amm.coins(0) == crvusd.address # crvUSD
    assert wbtc_amm.coins(1) == wbtc.address
    assert wbtc_controller.amm() == wbtc_amm.address
    assert wbtc_controller.collateral_token() == wbtc.address

    print('wBTC price:', wbtc_amm.price_oracle() / 1e18)

    # Borrow and check crvUSD amount
    wbtc.approve(wbtc_controller, 2**256 - 1, {'from': top_holder})
    try:
        # Cannot borrow 100k
        wbtc_controller.create_loan(10 **8, 100000 * 10** 18, 4, {'from': top_holder})
    except Exception:
        pass
    else:
        raise Exception("Didn't raise")
    # But can 10k
    wbtc_controller.create_loan(10 **8, 10000 * 10** 18, 4, {'from': top_holder})
    assert crvusd.balanceOf(top_holder) == 10000 * 10**18

    wbtc_controller.borrow_more(0, 10**18, {'from': top_holder})

```
