@chorus-one/ethereum
Version:
All-in-one toolkit for building staking dApps on Ethereum network
91 lines (80 loc) • 2.44 kB
text/typescript
import { Hex, encodeFunctionData } from 'viem'
import { StakewiseConnector } from '../connector'
import { keeperABI } from '../contracts/keeperAbi'
import { VaultABI } from '../contracts/vaultAbi'
import { Transaction } from '../types/transaction'
import { getHarvestParams } from '../utils/getHarvestParams'
export async function buildUnstakeTx (request: {
connector: StakewiseConnector
userAccount: Hex
vault: Hex
amount: bigint
}): Promise<Transaction> {
const { userAccount, connector, vault, amount } = request
const isCollateralized: boolean = await connector.eth.readContract({
abi: keeperABI,
address: connector.keeper,
functionName: 'isCollateralized',
args: [vault]
})
const shares: bigint = await connector.eth.readContract({
abi: VaultABI,
address: vault,
functionName: 'convertToShares',
args: [amount]
})
let tx: Hex
if (isCollateralized) {
// This branch of logic is invoked when the stake locked in vault
// is collateralized in form of beacon chain validators
const canHarvest = await connector.eth.readContract({
abi: keeperABI,
address: connector.keeper,
functionName: 'canHarvest',
args: [vault]
})
if (canHarvest) {
const harvestParams = await getHarvestParams(connector, vault)
const updateStateTx = encodeFunctionData({
abi: VaultABI,
functionName: 'updateState',
args: [
{
proof: harvestParams.proof,
rewardsRoot: harvestParams.rewardsRoot,
reward: harvestParams.reward,
unlockedMevReward: harvestParams.unlockedMevReward
}
]
})
const enterExitQueueTx = encodeFunctionData({
abi: VaultABI,
functionName: 'enterExitQueue',
args: [shares, userAccount]
})
tx = encodeFunctionData({
abi: VaultABI,
functionName: 'multicall',
args: [[updateStateTx, enterExitQueueTx]]
})
} else {
tx = encodeFunctionData({
abi: VaultABI,
functionName: 'enterExitQueue',
args: [shares, userAccount]
})
}
} else {
// This branch of logic is invoked when the stake locked in vault
// does not actually power any validators
tx = encodeFunctionData({
abi: VaultABI,
functionName: 'redeem',
args: [shares, userAccount]
})
}
return {
to: vault,
data: tx
}
}