Deleverage & Unhedge PT Long Position

Yield DevYield Dev
4 min read

Now that we have implemented our opening and closing scripts for our leveraged, delta neutral PT Long position and have written several useful utilities. Creating new scripts will be dead simple.

Let's start by deleveraging our position. In the event that wS price rises, while our position's USD equity will remain neutral, our collateralization ratio will approach liquidation. Thus we need a way to reduce our overall size in the position to make sure our starting capital remains large enough relative to the position size to collateralize the position.

Do do these we simply need to execute a swap of some portion of our HEDGED_TOKEN for the LIABILITY_TOKEN and use it to pay down our debt. Our exposure will remain neutral but our overall loan to value ratio will be reduced.

We can see that our previously written utility for this pattern batchSwapAndRepay will make implementing this a breeze. We just need to input the proper parameters in the context of reducing our leverage.

First setup our script to define the proper vaults associated with this trade, the same as the previous posts

// delverage.s.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;

import "./common/EScript.s.sol";
import {SonicLib} from "./common/SonicLib.sol";

contract DeleverageScript is EScript {
    function run() public {
        borrower = msg.sender;
        e_account = getSubaccount(borrower, 2);
        evc = IEVC(SonicLib.EVC);

        address LIABILITY_VAULT = SonicLib.EULER_WS_VAULT;
        address HEDGED_VAULT = SonicLib.EULER_PT_STS_VAULT;
        address COLLATERAL_VAULT = SonicLib.EULER_USDC_VAULT;
        address LIABILITY_TOKEN = SonicLib.WS;
        address HEDGED_TOKEN = SonicLib.PT_STS;
        address COLLATERAL_TOKEN = SonicLib.USDC;

        uint256 deleverage_amount = assetsBalance(HEDGED_VAULT) / 4;

        (string memory swapJson, string memory verifyJson) = getRoutingData(
            HEDGED_VAULT, LIABILITY_VAULT, HEDGED_TOKEN, LIABILITY_TOKEN, deleverage_amount
        );

        broadcastBatch(batchSwapAndRepay(
            HEDGED_VAULT, LIABILITY_VAULT, deleverage_amount, swapJson, verifyJson)
        );

        logPositionInfo(COLLATERAL_VAULT, HEDGED_VAULT, LIABILITY_VAULT);

    }
}

Now we calculate our deleverage_amount as the fraction of our HEDGED_TOKEN that we want to liquidate. In this example we will reduce our size by 1/4th (25%)

Now, we just need to fetch our routing payload, noting that we are swapping the HEDGED_TOKEN PT-stS into the LIABILITY_TOKEN wS, with the LIABILITY_VAULT as the ultimate destination for the output tokens.

Once, we have that payload our batchSwapAndRepay batch array will organize the operations to withdraw the PT-stS, execute the swap and repay the debt in the LIABILITY_VAULT.

Finally, we can see our balances show that our USD collateral remain the same and our HEDGED_TOKEN balance and LIABILITY_TOKEN debt are reduced by 1/4.

Unhedge

Just as easily as we deleveraged the position, we can unhedge it. We can gain exposure to the price movements of the underlying wS by simply swapping the COLLATERALTOKEN which we used as our hedge into the HEDGED_TOKEN giving us excess exposure to the HEDGE_TOKEN relative to our LIABILITY_TOKEN debt amount.

Again, we setup our script the same a before with all of the appropriate vaults labeled exactly the same.

// undehge.s.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;

import "./common/EScript.s.sol";
import {SonicLib} from "./common/SonicLib.sol";
import { IERC20 } from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";

contract UnhedgeScript is EScript {
    function run() public {
        borrower = msg.sender;
        e_account = getSubaccount(borrower, 2);
        evc = IEVC(SonicLib.EVC);

        address LIABILITY_VAULT = SonicLib.EULER_WS_VAULT;
        address HEDGED_VAULT = SonicLib.EULER_PT_STS_VAULT;
        address COLLATERAL_VAULT = SonicLib.EULER_USDC_VAULT;
        address LIABILITY_TOKEN = SonicLib.WS;
        address HEDGED_TOKEN = SonicLib.PT_STS;
        address COLLATERAL_TOKEN = SonicLib.USDC;

        uint256 collateral_unhedge_amount = assetsBalance(COLLATERAL_VAULT);

        (string memory swapJson, string memory verifyJson) = getRoutingData(
            COLLATERAL_VAULT, HEDGED_VAULT, COLLATERAL_TOKEN, HEDGED_TOKEN, collateral_unhedge_amount
        );

        broadcastBatch(batchWithdrawAndSwap(
            COLLATERAL_VAULT, collateral_unhedge_amount, swapJson, verifyJson)
        );

        logPositionInfo(COLLATERAL_VAULT, HEDGED_VAULT, LIABILITY_VAULT);
    }
}

In this example, we set the collateral_unhedge_amount to the total amount of our COLLATERAL_VAULT balance thus completely unhedging our position and gaining wS exposure equivalent to our starting capital.

We can also easily fetch the payload data, with the COLLATERAL_TOKEN (USDC) as the input and the HEDGED_TOKEN as the output with HEDGED_VAULT as the destination.

Once, we have the swap data, we can broadcast a batch constructed with the batchWithdrawAndSwap pattern using the COLLATERAL_VAULT as the _input_vault.

Just like that, we have converted the position to maximize our exposure to the underlying wS price movements. Here we can see how our script framework makes constructing new position's and managing existing one's a breeze, giving us almost infinite flexibility.

High yield defi engineering is available on demand at YieldDev Studio

Feel free to reach out on —> x for anything, technical or otherwise

Full code described above can be found on github

0
Subscribe to my newsletter

Read articles from Yield Dev directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yield Dev
Yield Dev