Skip to content
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

Staking limits #68

Merged
merged 50 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
2bdc9b5
Create `StakingParameters` struct
r-czajkowski Dec 7, 2023
5679d87
Set default staking parameters in constructor
r-czajkowski Dec 7, 2023
ae7b3fb
Implement min amount limit for a single deposit
r-czajkowski Dec 7, 2023
1765b6d
Fix typo
r-czajkowski Dec 7, 2023
5494c44
Simplify test
r-czajkowski Dec 7, 2023
15ff38d
Override `maxDeposit` fn
r-czajkowski Dec 7, 2023
0efc202
Implement staking limits in `mint` fn
r-czajkowski Dec 7, 2023
2fda404
Add fn that allows owner to update staking params
r-czajkowski Dec 8, 2023
7ae23cb
Add unit test for `updateStakingParameters` fn
r-czajkowski Dec 8, 2023
a5d022c
Fix unit tests
r-czajkowski Dec 8, 2023
4a1de54
Fix slither errors
r-czajkowski Dec 8, 2023
afc2323
Fix deployment scripts
r-czajkowski Dec 8, 2023
7b907fe
Simplify overridden `deposit` fn
r-czajkowski Dec 8, 2023
2ecd47f
Simplify the Acre constructor
r-czajkowski Dec 12, 2023
425a06f
Update `maxDeposit` fn
r-czajkowski Dec 12, 2023
8535cfe
Move the require check before `super.mint`
r-czajkowski Dec 12, 2023
ec6f06e
Update `updateStakingParameters` fn
r-czajkowski Dec 12, 2023
7516de4
Leave TODO in `updateStakingParameters`
r-czajkowski Dec 12, 2023
331c1d3
Define custom errors for the checks
r-czajkowski Dec 12, 2023
17dc55a
Merge branch 'main' into staking-limits
r-czajkowski Dec 13, 2023
f23a8e7
Merge branch 'main' into staking-limits
r-czajkowski Dec 19, 2023
bff9665
Update `mint` function
r-czajkowski Dec 19, 2023
9ed875d
Update `updateStakingParameters` function
r-czajkowski Dec 19, 2023
f9f230a
Rename error
r-czajkowski Dec 19, 2023
b2c4a80
Simplify `maxDeposit` function
r-czajkowski Dec 19, 2023
ea67712
Add unit test for `mint` function
r-czajkowski Dec 19, 2023
43f583d
Fix typo
r-czajkowski Dec 20, 2023
becb46e
Add unit tests for `maxMint` function
r-czajkowski Dec 20, 2023
1c42a37
Update validation of staking parameters
r-czajkowski Dec 20, 2023
a5903e3
Update `maxMint` function
r-czajkowski Dec 20, 2023
a13b09f
Get rid of `StakingParameter` struct
r-czajkowski Dec 20, 2023
31f74f2
Update `Acre` constructor
r-czajkowski Dec 21, 2023
5ec1b80
Rename error
r-czajkowski Dec 21, 2023
1f14cde
Update Acre docs
r-czajkowski Dec 21, 2023
e8f7aa1
Remove unnecessary test
r-czajkowski Dec 21, 2023
ab8d89c
Add `.withArgs` for all errors that have args
r-czajkowski Dec 21, 2023
0e33e4b
Celean up Acre unit tests
r-czajkowski Dec 21, 2023
3266007
Merge branch 'main' into staking-limits
r-czajkowski Dec 21, 2023
edd69cf
Add missing `await` in `before` test hook
r-czajkowski Dec 27, 2023
a373b59
Use `convertToShares` instead of `previewDeposit`
r-czajkowski Dec 27, 2023
f5a4429
Update `mint` test case
r-czajkowski Dec 27, 2023
fc5f585
Update `updateDepositParameters` fn
r-czajkowski Dec 27, 2023
1356fb0
Allow to remove the limit for deposits
r-czajkowski Dec 27, 2023
54bcf17
Update `maxMint` function
r-czajkowski Dec 28, 2023
0f8b830
Add unit tests for `deposit` function
r-czajkowski Dec 28, 2023
53ca7fc
Merge branch 'main' into staking-limits
r-czajkowski Dec 28, 2023
771553b
Fix slither error
r-czajkowski Dec 29, 2023
cc05de6
Fix typo
r-czajkowski Dec 29, 2023
d2fcf4a
Add new test case for staking
r-czajkowski Dec 29, 2023
1140bcb
Merge branch 'main' into staking-limits
r-czajkowski Dec 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 120 additions & 3 deletions core/contracts/Acre.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.21;

import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/// @title Acre
/// @notice This contract implements the ERC-4626 tokenized vault standard. By
Expand All @@ -14,12 +15,96 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";
/// of yield-bearing vaults. This contract facilitates the minting and
/// burning of shares (stBTC), which are represented as standard ERC20
/// tokens, providing a seamless exchange with tBTC tokens.
contract Acre is ERC4626 {
contract Acre is ERC4626, Ownable {
struct StakingParameters {
nkuba marked this conversation as resolved.
Show resolved Hide resolved
// Minimum amount for a single deposit operation.
uint256 minimumDepositAmount;
// Maximum total amount of tBTC token held by Acre.
uint256 maximumTotalAssets;
}

StakingParameters public stakingParameters;

event StakeReferral(bytes32 indexed referral, uint256 assets);
event StakingParametersUpdated(
uint256 minimumDepositAmount,
uint256 maximumTotalAssets
);

constructor(
IERC20 tbtc
) ERC4626(tbtc) ERC20("Acre Staked Bitcoin", "stBTC") {}
IERC20 tbtc,
address initialOwner
)
ERC4626(tbtc)
ERC20("Acre Staked Bitcoin", "stBTC")
Ownable(initialOwner)
nkuba marked this conversation as resolved.
Show resolved Hide resolved
dimpar marked this conversation as resolved.
Show resolved Hide resolved
{
stakingParameters.minimumDepositAmount = 0.01 ether; // 0.01 tBTC
stakingParameters.maximumTotalAssets = 25 ether; // 25 tBTC
}

/// @notice Updates parameters of staking.
nkuba marked this conversation as resolved.
Show resolved Hide resolved
/// @dev Requirements:
/// - Minimum deposit amount must be greater than zero,
/// - Minimum deposit amount must be greater than or equal to the
/// minimum deposit amount in the tBTC system,
/// - Maximum total assets must be greater than zero.
/// @param minimumDepositAmount New value of the minimum deposit amount. It
/// is the minimum amount for a single deposit operation.
/// @param maximumTotalAssets New value of the maximum total assets amount.
/// It is the maximum amount of the tBTC token that the Acre can
/// hold.
function updateStakingParameters(
nkuba marked this conversation as resolved.
Show resolved Hide resolved
uint256 minimumDepositAmount,
uint256 maximumTotalAssets
) external onlyOwner {
require(
minimumDepositAmount > 0,
"Minimum deposit amount must be greater than zero"
);

// TODO: Do we need this requirement?
nkuba marked this conversation as resolved.
Show resolved Hide resolved
require(
minimumDepositAmount >= _getTBTCSystemMinDepositAmount(),
"Minimum deposit amount must be greater than or to the equal minimum deposit amount in tBTC system"
dimpar marked this conversation as resolved.
Show resolved Hide resolved
);

require(
maximumTotalAssets > 0,
"Maximum total assets amount must be greater than zero"
);

stakingParameters.minimumDepositAmount = minimumDepositAmount;
stakingParameters.maximumTotalAssets = maximumTotalAssets;

emit StakingParametersUpdated(minimumDepositAmount, maximumTotalAssets);
}

function deposit(
nkuba marked this conversation as resolved.
Show resolved Hide resolved
uint256 assets,
address receiver
) public override returns (uint256) {
require(
nkuba marked this conversation as resolved.
Show resolved Hide resolved
assets >= stakingParameters.minimumDepositAmount,
"Amount is less than minimum"
);

return super.deposit(assets, receiver);
}

function mint(
dimpar marked this conversation as resolved.
Show resolved Hide resolved
uint256 shares,
address receiver
) public override returns (uint256) {
uint256 assets = super.mint(shares, receiver);

require(
assets >= stakingParameters.minimumDepositAmount,
"Amount is less than minimum"
);

return assets;
nkuba marked this conversation as resolved.
Show resolved Hide resolved
}

/// @notice Stakes a given amount of tBTC token and mints shares to a
/// receiver.
Expand All @@ -43,4 +128,36 @@ contract Acre is ERC4626 {

return shares;
}

/// @notice Returns the maximum amount of the tBTC token that can be
/// deposited into the vault for the receiver, through a deposit
/// call. It takes into account the staking parameter, maximum total
nkuba marked this conversation as resolved.
Show resolved Hide resolved
/// assets, which determines the total amount of tBTC token held by
/// Acre.
/// @return The maximum amount of the tBTC token.
function maxDeposit(address) public view override returns (uint256) {
return stakingParameters.maximumTotalAssets - totalAssets();
nkuba marked this conversation as resolved.
Show resolved Hide resolved
}

/// @notice Returns the maximum amount of the vault shares that can be
/// minted for the receiver, through a mint call.
/// @dev Since the Acre contract limits the maximum total tBTC tokens this
/// function converts the maximum deposit amount to shares.
/// @return The maximum amount of the vault shares.
function maxMint(address receiver) public view override returns (uint256) {
return previewDeposit(maxDeposit(receiver));
nkuba marked this conversation as resolved.
Show resolved Hide resolved
}

function _getTBTCSystemMinDepositAmount() private pure returns (uint256) {
// TODO: Implement if we want to make sure the minimum deposit amount is
// greater than or equal the minimum dposit amount in the tBTC system.

// (uint64 depositDustThreshold, , , ) = tbtcBridge.depositParameters();

// // The `depositDustThreshold` is in satoshi so we need to cast to tBTC
// // decimals.
// return 10 ** (ERC20(asset()).decimals() - 8) * depositDustThreshold;

return 0.01 ether; // 0.01 tBTC
}
}
2 changes: 1 addition & 1 deletion core/deploy/01_deploy_acre.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {

await deployments.deploy("Acre", {
from: deployer,
args: [tbtc.address],
args: [tbtc.address, deployer],
log: true,
waitConfirmations: 1,
})
Expand Down
Loading