Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into bitcoin-redeemer-2
Browse files Browse the repository at this point in the history
  • Loading branch information
nkuba committed Apr 9, 2024
2 parents 614dfa0 + e26e660 commit d59a027
Show file tree
Hide file tree
Showing 31 changed files with 202 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import "@keep-network/tbtc-v2/contracts/integrator/AbstractTBTCDepositor.sol";

import {stBTC} from "./stBTC.sol";

/// @title Acre Bitcoin Depositor contract.
/// @title Bitcoin Depositor contract.
/// @notice The contract integrates Acre staking with tBTC minting.
/// User who wants to stake BTC in Acre should submit a Bitcoin transaction
/// to the most recently created off-chain ECDSA wallets of the tBTC Bridge
Expand All @@ -35,10 +35,7 @@ import {stBTC} from "./stBTC.sol";
/// Depositor address. After tBTC is minted to the Depositor, on the stake
/// finalization tBTC is staked in Acre and stBTC shares are emitted
/// to the staker.
contract AcreBitcoinDepositor is
AbstractTBTCDepositor,
Ownable2StepUpgradeable
{
contract BitcoinDepositor is AbstractTBTCDepositor, Ownable2StepUpgradeable {
using SafeERC20 for IERC20;

/// @notice State of the stake request.
Expand Down Expand Up @@ -146,7 +143,7 @@ contract AcreBitcoinDepositor is
_disableInitializers();
}

/// @notice Acre Bitcoin Depositor contract initializer.
/// @notice Bitcoin Depositor contract initializer.
/// @param bridge tBTC Bridge contract instance.
/// @param tbtcVault tBTC Vault contract instance.
/// @param _tbtcToken tBTC token contract instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* solhint-disable func-name-mixedcase */
pragma solidity ^0.8.21;

import {AcreBitcoinDepositor} from "../AcreBitcoinDepositor.sol";
import {BitcoinDepositor} from "../BitcoinDepositor.sol";
import {MockBridge, MockTBTCVault} from "@keep-network/tbtc-v2/contracts/test/TestTBTCDepositor.sol";
import {IBridge} from "@keep-network/tbtc-v2/contracts/integrator/IBridge.sol";
import {IBridgeTypes} from "@keep-network/tbtc-v2/contracts/integrator/IBridge.sol";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,11 @@ import "@keep-network/tbtc-v2/contracts/integrator/AbstractTBTCDepositor.sol";

import {stBTC} from "../../stBTC.sol";

/// @title AcreBitcoinDepositorV2
/// @dev This is a contract used to test Acre Bitcoin Depositor upgradeability.
/// It is a copy of AcreBitcoinDepositor contract with some differences
/// @title BitcoinDepositorV2
/// @dev This is a contract used to test Bitcoin Depositor upgradeability.
/// It is a copy of BitcoinDepositor contract with some differences
/// marked with `TEST:` comments.
contract AcreBitcoinDepositorV2 is
AbstractTBTCDepositor,
Ownable2StepUpgradeable
{
contract BitcoinDepositorV2 is AbstractTBTCDepositor, Ownable2StepUpgradeable {
using SafeERC20 for IERC20;

/// @notice State of the stake request.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const tbtc = await deployments.get("TBTC")
const stbtc = await deployments.get("stBTC")

const [, acreBitcoinDepositorDeployment] = await helpers.upgrades.deployProxy(
"AcreBitcoinDepositor",
const [, deployment] = await helpers.upgrades.deployProxy(
"BitcoinDepositor",
{
factoryOpts: {
signer: deployer,
Expand All @@ -31,21 +31,15 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
},
)

if (
acreBitcoinDepositorDeployment.transactionHash &&
hre.network.tags.etherscan
) {
await waitForTransaction(
hre,
acreBitcoinDepositorDeployment.transactionHash,
)
await helpers.etherscan.verify(acreBitcoinDepositorDeployment)
if (deployment.transactionHash && hre.network.tags.etherscan) {
await waitForTransaction(hre, deployment.transactionHash)
await helpers.etherscan.verify(deployment)
}

// TODO: Add Tenderly verification
}

export default func

func.tags = ["AcreBitcoinDepositor"]
func.tags = ["BitcoinDepositor"]
func.dependencies = ["TBTC", "stBTC"]
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const { deployer, governance } = await getNamedAccounts()
const { log } = deployments

log(
`transferring ownership of AcreBitcoinDepositor contract to ${governance}`,
)
log(`transferring ownership of BitcoinDepositor contract to ${governance}`)

await deployments.execute(
"AcreBitcoinDepositor",
"BitcoinDepositor",
{ from: deployer, log: true, waitConfirmations: 1 },
"transferOwnership",
governance,
)

if (hre.network.name !== "mainnet") {
await deployments.execute(
"AcreBitcoinDepositor",
"BitcoinDepositor",
{ from: governance, log: true, waitConfirmations: 1 },
"acceptOwnership",
)
Expand All @@ -28,6 +26,6 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {

export default func

func.tags = ["TransferOwnershipAcreBitcoinDepositor"]
func.dependencies = ["AcreBitcoinDepositor"]
func.tags = ["TransferOwnershipBitcoinDepositor"]
func.dependencies = ["BitcoinDepositor"]
func.runAtTheEnd = true
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
StBTC,
BridgeStub,
TBTCVaultStub,
AcreBitcoinDepositor,
BitcoinDepositor,
TestERC20,
} from "../typechain"
import { deployment } from "./helpers"
Expand All @@ -30,7 +30,7 @@ async function fixture() {
const { lastBlockTime } = helpers.time
const { getNamedSigners, getUnnamedSigners } = helpers.signers

describe("AcreBitcoinDepositor", () => {
describe("BitcoinDepositor", () => {
const defaultDepositDustThreshold = 1000000 // 1000000 satoshi = 0.01 BTC
const defaultDepositTreasuryFeeDivisor = 2000 // 1/2000 = 0.05% = 0.0005
const defaultDepositTxMaxFee = 1000 // 1000 satoshi = 0.00001 BTC
Expand All @@ -48,7 +48,7 @@ describe("AcreBitcoinDepositor", () => {
const depositorFee = to1ePrecision(10, 10) // 10 satoshi
const amountToStake = to1ePrecision(896501, 8) // 8965,01 satoshi

let bitcoinDepositor: AcreBitcoinDepositor
let bitcoinDepositor: BitcoinDepositor
let tbtcBridge: BridgeStub
let tbtcVault: TBTCVaultStub
let stbtc: StBTC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { beforeAfterSnapshotWrapper, deployment } from "./helpers"
import {
TestERC20,
StBTC,
AcreBitcoinDepositor,
BitcoinDepositor,
BridgeStub,
TBTCVaultStub,
AcreBitcoinDepositorV2,
BitcoinDepositorV2,
} from "../typechain"
import { to1e18 } from "./utils"

Expand All @@ -24,12 +24,12 @@ async function fixture() {
return { tbtc, stbtc, bitcoinDepositor, tbtcBridge, tbtcVault }
}

describe("AcreBitcoinDepositor contract upgrade", () => {
describe("BitcoinDepositor contract upgrade", () => {
let tbtc: TestERC20
let tbtcBridge: BridgeStub
let tbtcVault: TBTCVaultStub
let stbtc: StBTC
let bitcoinDepositor: AcreBitcoinDepositor
let bitcoinDepositor: BitcoinDepositor
let governance: HardhatEthersSigner

before(async () => {
Expand All @@ -40,7 +40,7 @@ describe("AcreBitcoinDepositor contract upgrade", () => {

context("when upgrading to a valid contract", () => {
const newVariable = 1n
let bitcoinDepositorV2: AcreBitcoinDepositorV2
let bitcoinDepositorV2: BitcoinDepositorV2
let v1InitialParameters: {
minStakeAmount: bigint
depositorFeeDivisor: bigint
Expand All @@ -59,8 +59,8 @@ describe("AcreBitcoinDepositor contract upgrade", () => {
}

const [upgradedDepositor] = await helpers.upgrades.upgradeProxy(
"AcreBitcoinDepositor",
"AcreBitcoinDepositorV2",
"BitcoinDepositor",
"BitcoinDepositorV2",
{
factoryOpts: { signer: governance },
proxyOpts: {
Expand All @@ -72,8 +72,7 @@ describe("AcreBitcoinDepositor contract upgrade", () => {
},
)

bitcoinDepositorV2 =
upgradedDepositor as unknown as AcreBitcoinDepositorV2
bitcoinDepositorV2 = upgradedDepositor as unknown as BitcoinDepositorV2
})

it("new instance should have the same address as the old one", async () => {
Expand Down
7 changes: 3 additions & 4 deletions core/test/helpers/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type {
BridgeStub,
TestERC4626,
TBTCVaultStub,
AcreBitcoinDepositor,
BitcoinDepositor,
BitcoinRedeemer,
TestTBTC,
} from "../../typechain"
Expand All @@ -17,9 +17,8 @@ export async function deployment() {
await deployments.fixture()

const stbtc: stBTC = await getDeployedContract("stBTC")
const bitcoinDepositor: AcreBitcoinDepositor = await getDeployedContract(
"AcreBitcoinDepositor",
)
const bitcoinDepositor: BitcoinDepositor =
await getDeployedContract("BitcoinDepositor")
const bitcoinRedeemer: BitcoinRedeemer =
await getDeployedContract("BitcoinRedeemer")

Expand Down
5 changes: 3 additions & 2 deletions dapp/src/components/LiquidStakingTokenPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
IconButton,
} from "@chakra-ui/react"
import { SizeType } from "#/types"
import { useDocsDrawer, useWalletContext } from "#/hooks"
import { useDocsDrawer, useSharesBalance, useWalletContext } from "#/hooks"
import { TextMd, TextSm } from "./shared/Typography"
import Alert from "./shared/Alert"
import { CurrencyBalance } from "./shared/CurrencyBalance"
Expand All @@ -23,6 +23,7 @@ export function LiquidStakingTokenPopover({
}: LiquidStakingTokenPopoverProps) {
const { isConnected } = useWalletContext()
const { onOpen: openDocsDrawer } = useDocsDrawer()
const sharesBalance = useSharesBalance()

return (
<Popover variant="no-transform" {...props}>
Expand Down Expand Up @@ -50,7 +51,7 @@ export function LiquidStakingTokenPopover({
<PopoverBody p={0}>
<TextMd fontWeight="bold">Liquid staking token</TextMd>
<CurrencyBalance
amount="912312331"
amount={sharesBalance.toString()}
variant="greater-balance-xl"
currency="stbtc"
/>
Expand Down
1 change: 1 addition & 0 deletions dapp/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ export * from "./useInitApp"
export * from "./useCurrencyConversion"
export * from "./useDepositTelemetry"
export * from "./useFetchBTCPriceUSD"
export * from "./useFetchBTCBalance"
export * from "./useSize"
2 changes: 2 additions & 0 deletions dapp/src/hooks/store/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from "./useAppDispatch"
export * from "./useAppSelector"
export * from "./useEstimatedBTCBalance"
export * from "./useSharesBalance"
6 changes: 6 additions & 0 deletions dapp/src/hooks/store/useEstimatedBTCBalance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { selectEstimatedBtcBalance } from "#/store/btc"
import { useAppSelector } from "./useAppSelector"

export function useEstimatedBTCBalance() {
return useAppSelector(selectEstimatedBtcBalance)
}
6 changes: 6 additions & 0 deletions dapp/src/hooks/store/useSharesBalance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { selectSharesBalance } from "#/store/btc"
import { useAppSelector } from "./useAppSelector"

export function useSharesBalance() {
return useAppSelector(selectSharesBalance)
}
28 changes: 28 additions & 0 deletions dapp/src/hooks/useFetchBTCBalance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useEffect } from "react"
import { EthereumAddress } from "@acre-btc/sdk"
import { useAcreContext } from "#/acre-react/hooks"
import { logPromiseFailure } from "#/utils"
import { setEstimatedBtcBalance, setSharesBalance } from "#/store/btc"
import { useWalletContext } from "./useWalletContext"
import { useAppDispatch } from "./store"

export function useFetchBTCBalance() {
const { acre, isInitialized } = useAcreContext()
const { ethAccount } = useWalletContext()
const dispatch = useAppDispatch()

useEffect(() => {
const getBtcBalance = async () => {
if (!isInitialized || !ethAccount || !acre) return

const chainIdentifier = EthereumAddress.from(ethAccount.address)
const sharesBalance = await acre.staking.sharesBalance(chainIdentifier)
const estimatedBitcoinBalance =
await acre.staking.estimatedBitcoinBalance(chainIdentifier)

dispatch(setSharesBalance(sharesBalance))
dispatch(setEstimatedBtcBalance(estimatedBitcoinBalance))
}
logPromiseFailure(getBtcBalance())
}, [acre, isInitialized, ethAccount, dispatch])
}
2 changes: 2 additions & 0 deletions dapp/src/hooks/useInitApp.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { useSentry } from "./sentry"
import { useInitializeAcreSdk } from "./useInitializeAcreSdk"
import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD"
import { useFetchBTCBalance } from "./useFetchBTCBalance"

export function useInitApp() {
// TODO: Let's uncomment when dark mode is ready
// useDetectThemeMode()
useSentry()
useInitializeAcreSdk()
useFetchBTCPriceUSD()
useFetchBTCBalance()
}
4 changes: 3 additions & 1 deletion dapp/src/pages/OverviewPage/PositionDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import { CurrencyBalanceWithConversion } from "#/components/shared/CurrencyBalan
import { TextMd } from "#/components/shared/Typography"
import { ACTION_FLOW_TYPES, ActionFlowType } from "#/types"
import TransactionModal from "#/components/TransactionModal"
import { useEstimatedBTCBalance } from "#/hooks/store"
import { LiquidStakingTokenPopover } from "#/components/LiquidStakingTokenPopover"
import { useSize } from "#/hooks"

export default function PositionDetails(props: CardProps) {
const estimatedBtcBalance = useEstimatedBTCBalance()
const { ref, size } = useSize()

const [actionFlowType, setActionFlowType] = useState<
Expand All @@ -35,7 +37,7 @@ export default function PositionDetails(props: CardProps) {
<CurrencyBalanceWithConversion
from={{
currency: "bitcoin",
amount: "2398567898",
amount: estimatedBtcBalance.toString(),
variant: "greater-balance-xl",
symbolFontWeight: "semibold",
}}
Expand Down
7 changes: 6 additions & 1 deletion dapp/src/store/btc/btcSelector.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { RootState } from ".."

export const selectBtcUsdPrice = (state: RootState) => state.btc.usdPrice
export const selectEstimatedBtcBalance = (state: RootState): bigint =>
state.btc.estimatedBtcBalance
export const selectSharesBalance = (state: RootState): bigint =>
state.btc.sharesBalance
export const selectBtcUsdPrice = (state: RootState): number =>
state.btc.usdPrice
15 changes: 14 additions & 1 deletion dapp/src/store/btc/btcSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ import { PayloadAction, createSlice } from "@reduxjs/toolkit"
import { fetchBTCPriceUSD } from "./btcThunk"

type BtcState = {
estimatedBtcBalance: bigint
sharesBalance: bigint
isLoadingPriceUSD: boolean
usdPrice: number
}

const initialState: BtcState = {
estimatedBtcBalance: 0n,
sharesBalance: 0n,
isLoadingPriceUSD: false,
usdPrice: 0,
}
Expand All @@ -15,7 +19,14 @@ const initialState: BtcState = {
export const btcSlice = createSlice({
name: "btc",
initialState,
reducers: {},
reducers: {
setSharesBalance(state, action: PayloadAction<bigint>) {
state.sharesBalance = action.payload
},
setEstimatedBtcBalance(state, action: PayloadAction<bigint>) {
state.estimatedBtcBalance = action.payload
},
},
extraReducers: (builder) => {
builder.addCase(fetchBTCPriceUSD.pending, (state) => {
state.isLoadingPriceUSD = true
Expand All @@ -32,3 +43,5 @@ export const btcSlice = createSlice({
)
},
})

export const { setSharesBalance, setEstimatedBtcBalance } = btcSlice.actions
Loading

0 comments on commit d59a027

Please sign in to comment.