-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial implementation of Bitcoin depositor (tBTC Depositor) #91
Merged
Merged
Changes from all commits
Commits
Show all changes
139 commits
Select commit
Hold shift + click to select a range
f57fe76
Define external tbtc interfaces
nkuba a6d27d4
Implement tBTC Depositor contract
nkuba a95e09d
Add dependency to @keep-network/bitcoin-spv-sol
nkuba 9733704
Add TODO about minimum limits
nkuba c1b4b12
Change referral type to uint16
nkuba 6f48f76
Update referral type in StakeReferral event
nkuba 27fb5ff
Fix formatting
nkuba d409aea
Fix ducumentation
nkuba e719485
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba 4ea8617
Emit events on stake initialization and finalization
nkuba be66889
Add missing dependency in Acre deployment script
nkuba e9af2ac
Make TbtcDepositor contract Ownable
nkuba c2720af
Define tBTC Depositor's depositor fee
nkuba 74c7c30
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba fda93b7
Define treasury address reference in Acre contract
nkuba dee6db3
Document minimum deposit amount
nkuba f24ccb8
Add function to help estimate fees
nkuba 53e33f0
Add unit tests for extra data encode/decode functions
nkuba 0648cb9
Add unit tests for updateDepositorFeeDivisor
nkuba 9ee08d6
Use beforeAfterSnapshotWrapper in updateDepositorFeeDivisor tests
nkuba a111eba
Add unit test for calculateDepositKey function
nkuba 81d9831
Add unit tests for initializeStake function
nkuba 6f722e9
Add helper function to get latest block timestamp
nkuba f009b3c
Add test data for tBTC deposit
nkuba a9945a8
Add treasury address reference to Acre deployment script
nkuba b20f02b
Remove only from test
nkuba 81aa38e
Add unit tests for finalizeStake function
nkuba b6f52f4
Add clarification for depositor address check
nkuba b918ee8
Use Math.min for OM fee divisors comparison
nkuba 0909d82
Add name and symbol to TestERC20 constructor
nkuba 4ca73bf
Remove estimateFee function
nkuba 89d6df3
Add tBTC Bridge and tBTC Vault contracts stubs
nkuba 8ed2a3b
Update deployment scripts for tBTC Depositor
nkuba 7c2fea3
Fix solhint problems
nkuba 5bd8a40
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba c4c19b3
Let the user recall bridged tBTC
nkuba 01c8feb
Add tBTC token reference in tBTC Depositor contract
nkuba 4d5cdbb
Check revealed tBTC Vault matches the expected
nkuba 2b9b222
Update initialize/finalize stake request function names in tests
nkuba 8b5fdc8
Move TBTCVault check to the beginign of initializeStakeRequest
nkuba c78ec0a
Move Depositor address check to initializeStakeRequest
nkuba e1e9a1e
Update tests to reflect vault and depositor checks change
nkuba 3d168b1
Fix conversion of fees from sat to tBTC
nkuba a06822a
Update unit tests for notify/finalize function changes
nkuba 2c39ed5
Implement TBTCDepositorProxy
nkuba a82393e
Update unit tests for changes in TbtcDepositor contract
nkuba 6d8d8c7
Remove external tbtc contracts
nkuba 2a401f0
Update stub contracts
nkuba 83da0c4
Disable no-use-before-define rule
nkuba 5283f1e
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba 10bcee4
Rename Acre contact references to stBTC
nkuba d5fe01f
Set entry fee basis points to zero
nkuba 4dc776f
Move TbtcDepositor.sol file
nkuba 10c4126
Move TbtcDepositor.sol file
nkuba 9e9d975
Enable encode extra data test cases
nkuba 0c151ac
Add unit tests for recallStakeRequest
nkuba 610abb5
Update StakeRequestRecalled event
nkuba 1d3cea3
Convert depositKey value to bigint
nkuba 850f980
Upgrade dependency to tbtc-v2
nkuba cbf198b
Update tBTC contract mocks
nkuba e8227ab
Update name of used initialize function
nkuba e14ff0e
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba debc8dc
Fix not needed import
nkuba 873e1cd
Update reference to @keep-network/tbtc-v2
nkuba 1237ced
Fix slither errors
nkuba f541f7d
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba 8fdab6f
Remove unused imports
nkuba fac63fd
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba bcb127e
Clarify minting process in docs
nkuba defea02
Use Ownable2Step instead of Ownable
nkuba ec35bed
Accept ownership transfer in deployment script
nkuba 60740dd
Rename amount related variables
nkuba 68f58b4
Introduce recalledAt property
nkuba 932bd1b
Use helpers from @keep-network/hardhat-helpers
nkuba c73e98d
Fix tag of onwership transfer script
nkuba 4c72591
Use Ownable2Step in all contracts
nkuba 563cca9
Combine notifyBridgingCompleted and finalizeStakeRequest
nkuba e3afe46
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba abfe788
Check if notifyBridgingCompleted was already called
nkuba 14e0c65
Update dependency to tbtc-v2 contracts
nkuba 8c02617
Add decodeExtraData function back
nkuba ecdf80f
Introduce finalizeStakeRequest function and queue
nkuba c95f17a
Update unit tests after queue updates
nkuba 7741b92
Update function order in TbtcDepositor contract
nkuba a56117e
Rename TbtcDepositor to AcreBitcoinDepositor
nkuba e3cbfdc
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba 3485752
Add a TODO to SDK about renaming TBTC Depositor
nkuba a72344c
Update tbtc-v2 dependency to 1.6.0-dev.21
nkuba 7295110
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba e30ff01
Remove updateEntryFeeBasisPoints call in tests
nkuba 3e69dcd
Ensure max value can be set for fee divisor
nkuba f4b4c27
Use enum to track request state
nkuba b3949fe
Don't underscore parameters
nkuba 4f4dd4a
User custom error instead of require
nkuba 7a13d75
Add TODO to make contract pausable
nkuba 005435d
Rename receiver to staker
nkuba 29d054a
Remove empty line
nkuba 9d745ce
Move decodeExtraData closer to emit BridgingCompleted
nkuba 313d193
Clarify BridgingCompleted event emission
nkuba 0b03bae
queueForStaking -> queueStake
nkuba fbbf10d
initializeStakeRequest -> initializeStake
nkuba 327c9f4
finalizeStakeRequest -> finalizeStake
nkuba f226b56
Update test cases names for stakes
nkuba 7f94c44
Minor docs improvements
nkuba ac3f268
Remove underscores for constructor params names
nkuba e7b7e07
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba 628de75
Use initializeStake function instead of initializeStakeRequest
nkuba 7529547
Fix initializeStake func name in depositor mock
nkuba 18dc65c
Exclude contracts/test dir from slither checks
nkuba 6f48b16
Rename recallFromQueue to cancelQueuedStake
nkuba 55087ae
Rename stakeFromQueue to finalizeQueuedStake
nkuba 3e1f42c
Add misfund recovery to the Depositor contract
nkuba 0ff413a
Add missing TestERC721 type import
nkuba 28b65a2
Add TestERC721 contract implementation
nkuba c03c37a
Store queued amount as uint88
nkuba 79f4d43
Re-order state variables to optimize storage
nkuba 48f6c37
Remove immutable variables from AcreBitcoinDepositor
nkuba 591a9b3
Update TBTCDepositorProxy ref to AbstractTBTCDepositor
nkuba e0b8d6c
Check if depositor balance is enough for bridged amount
nkuba ea20b43
Revert "Add misfund recovery to the Depositor contract"
nkuba 879eab5
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba 4489d12
Disable slither checks for non-immutable vars
nkuba e3ff790
Remove unused import
nkuba c99f286
Fix the name of slither rule to disable
nkuba 0355f7c
Fix slither disable rule
nkuba cfaec75
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba 0ca396b
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba c2b54db
Add etherscan verification for AcreBitcoinDepositor
nkuba c0c0746
Fix etherscan verification for Dispatcher
nkuba 0e72db4
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba 6fc9ea9
Merge branch 'main' into tbtc-depositor
nkuba 2e03a62
Docs improvements
nkuba 46ae9a1
Improve variables naming
nkuba a335dad
Reorganize test contracts
nkuba cebb35e
Use waitConfirmationsNumber in deployment
nkuba a4b85c8
Merge remote-tracking branch 'origin/main' into tbtc-depositor
nkuba b6eea22
Disable func-name-mixedcase solhint rule for harness contract
nkuba 54a2427
Use waitConfirmationsNumber in all deploy scripts
nkuba e4d3062
Add missing waitConfirmationsNumber import
nkuba File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
/* solhint-disable func-name-mixedcase */ | ||
pragma solidity ^0.8.21; | ||
|
||
import {AcreBitcoinDepositor} from "../AcreBitcoinDepositor.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"; | ||
|
||
import {TestERC20} from "./TestERC20.sol"; | ||
|
||
/// @dev A test contract to expose internal function from AcreBitcoinDepositor contract. | ||
/// This solution follows Foundry recommendation: | ||
/// https://book.getfoundry.sh/tutorials/best-practices#internal-functions | ||
contract AcreBitcoinDepositorHarness is AcreBitcoinDepositor { | ||
constructor( | ||
address bridge, | ||
address tbtcVault, | ||
address tbtcToken, | ||
address stbtc | ||
) AcreBitcoinDepositor(bridge, tbtcVault, tbtcToken, stbtc) {} | ||
|
||
function exposed_finalizeBridging( | ||
uint256 depositKey | ||
) external returns (uint256 amountToStake, address staker) { | ||
return finalizeBridging(depositKey); | ||
} | ||
} | ||
|
||
/// @dev A test contract to stub tBTC Bridge contract. | ||
contract BridgeStub is MockBridge {} | ||
|
||
/// @dev A test contract to stub tBTC Vault contract. | ||
contract TBTCVaultStub is MockTBTCVault { | ||
TestERC20 public immutable tbtc; | ||
IBridge public immutable bridge; | ||
|
||
/// @notice Multiplier to convert satoshi to TBTC token units. | ||
uint256 public constant SATOSHI_MULTIPLIER = 10 ** 10; | ||
|
||
constructor(TestERC20 _tbtc, IBridge _bridge) { | ||
tbtc = _tbtc; | ||
bridge = _bridge; | ||
} | ||
|
||
function finalizeOptimisticMintingRequest( | ||
uint256 depositKey | ||
) public override { | ||
IBridgeTypes.DepositRequest memory deposit = bridge.deposits( | ||
depositKey | ||
); | ||
|
||
uint256 amountSubTreasury = (deposit.amount - deposit.treasuryFee) * | ||
SATOSHI_MULTIPLIER; | ||
|
||
uint256 omFee = optimisticMintingFeeDivisor > 0 | ||
? (amountSubTreasury / optimisticMintingFeeDivisor) | ||
: 0; | ||
|
||
// The deposit transaction max fee is in the 1e8 satoshi precision. | ||
// We need to convert them to the 1e18 TBTC precision. | ||
// slither-disable-next-line unused-return | ||
(, , uint64 depositTxMaxFee, ) = bridge.depositParameters(); | ||
uint256 txMaxFee = depositTxMaxFee * SATOSHI_MULTIPLIER; | ||
|
||
uint256 amountToMint = amountSubTreasury - omFee - txMaxFee; | ||
|
||
finalizeOptimisticMintingRequestWithAmount(depositKey, amountToMint); | ||
} | ||
|
||
function finalizeOptimisticMintingRequestWithAmount( | ||
uint256 depositKey, | ||
uint256 amountToMint | ||
) public { | ||
MockTBTCVault.finalizeOptimisticMintingRequest(depositKey); | ||
|
||
tbtc.mint(bridge.deposits(depositKey).depositor, amountToMint); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
import type { | ||
HardhatNetworkConfig, | ||
HardhatRuntimeEnvironment, | ||
} from "hardhat/types" | ||
import { isNonZeroAddress } from "../helpers/address" | ||
import { waitConfirmationsNumber } from "../helpers/deployment" | ||
|
||
const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { | ||
const { getNamedAccounts, deployments } = hre | ||
const { log } = deployments | ||
const { deployer } = await getNamedAccounts() | ||
|
||
const bridge = await deployments.getOrNull("Bridge") | ||
|
||
if (bridge && isNonZeroAddress(bridge.address)) { | ||
log(`using Bridge contract at ${bridge.address}`) | ||
} else if ((hre.network.config as HardhatNetworkConfig)?.forking?.enabled) { | ||
throw new Error("deployed Bridge contract not found") | ||
} else { | ||
log("deploying Bridge contract stub") | ||
|
||
await deployments.deploy("Bridge", { | ||
contract: "BridgeStub", | ||
args: [], | ||
from: deployer, | ||
log: true, | ||
waitConfirmations: waitConfirmationsNumber(hre), | ||
}) | ||
} | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["TBTC", "Bridge"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
import type { | ||
HardhatNetworkConfig, | ||
HardhatRuntimeEnvironment, | ||
} from "hardhat/types" | ||
import { isNonZeroAddress } from "../helpers/address" | ||
import { waitConfirmationsNumber } from "../helpers/deployment" | ||
|
||
const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { | ||
const { getNamedAccounts, deployments } = hre | ||
const { log } = deployments | ||
const { deployer } = await getNamedAccounts() | ||
|
||
const tbtcVault = await deployments.getOrNull("TBTCVault") | ||
|
||
if (tbtcVault && isNonZeroAddress(tbtcVault.address)) { | ||
log(`using TBTCVault contract at ${tbtcVault.address}`) | ||
} else if ( | ||
!hre.network.tags.allowStubs || | ||
(hre.network.config as HardhatNetworkConfig)?.forking?.enabled | ||
) { | ||
throw new Error("deployed TBTCVault contract not found") | ||
} else { | ||
log("deploying TBTCVault contract stub") | ||
|
||
const tbtc = await deployments.get("TBTC") | ||
const bridge = await deployments.get("Bridge") | ||
|
||
await deployments.deploy("TBTCVault", { | ||
contract: "TBTCVaultStub", | ||
args: [tbtc.address, bridge.address], | ||
from: deployer, | ||
log: true, | ||
waitConfirmations: waitConfirmationsNumber(hre), | ||
}) | ||
} | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["TBTC", "TBTCVault"] | ||
func.dependencies = ["TBTCToken", "Bridge"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import type { DeployFunction } from "hardhat-deploy/types" | ||
import type { HardhatRuntimeEnvironment } from "hardhat/types" | ||
import { waitConfirmationsNumber } from "../helpers/deployment" | ||
|
||
const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { | ||
const { getNamedAccounts, deployments, helpers } = hre | ||
const { deployer } = await getNamedAccounts() | ||
|
||
const bridge = await deployments.get("Bridge") | ||
const tbtcVault = await deployments.get("TBTCVault") | ||
const tbtc = await deployments.get("TBTC") | ||
const stbtc = await deployments.get("stBTC") | ||
|
||
const depositor = await deployments.deploy("AcreBitcoinDepositor", { | ||
contract: | ||
process.env.HARDHAT_TEST === "true" | ||
? "AcreBitcoinDepositorHarness" | ||
: "AcreBitcoinDepositor", | ||
from: deployer, | ||
args: [bridge.address, tbtcVault.address, tbtc.address, stbtc.address], | ||
log: true, | ||
waitConfirmations: waitConfirmationsNumber(hre), | ||
}) | ||
|
||
if (hre.network.tags.etherscan) { | ||
await helpers.etherscan.verify(depositor) | ||
} | ||
|
||
// TODO: Add Tenderly verification | ||
} | ||
|
||
export default func | ||
|
||
func.tags = ["AcreBitcoinDepositor"] | ||
func.dependencies = ["TBTC", "stBTC"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not biggy, but did you consider using
func.skip
just like we use for example in00_resolve_testing_erc4626.ts
? This way we'd need to almost duplicate this file, but we avoid logic in the deployment contracts and no need to use"test": "HARDHAT_TEST=true hardhat test"
in package.json. Up to you.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I wanted to achieve here is to deploy the contract but if the deployment is invoked for unit test execution use the alternative
AcreBitcoinDepositorHarness
contract. So the script should be executed always, just with a different contract.I'm not sure what would be the best way to do it with the
func.skip
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I know what you're trying to achieve. My proposition was having two deployment files:
03_deploy_acre_bitcoin_depositor.ts
and03_test_deploy_acre_bitcoin_depositor.ts
. In the first one we add skip if the network is hardhat. For the latter script we can add skip in case the network is other than hardhat. This way the logic from deployment script and package.json will go away. Anyway, this is just another option, non blocker and up to you.