Skip to content

Commit

Permalink
Merge branch 'main' into dashboard/current-season-card
Browse files Browse the repository at this point in the history
  • Loading branch information
kpyszkowski authored May 14, 2024
2 parents bc6a405 + 7e9bc84 commit 76f4794
Show file tree
Hide file tree
Showing 25 changed files with 318 additions and 430 deletions.
14 changes: 12 additions & 2 deletions dapp/src/constants/chains.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { Chain } from "#/types"
import { EthereumNetwork, BitcoinNetwork } from "@acre-btc/sdk"

export const BLOCK_EXPLORER: Record<Chain, { title: string; url: string }> = {
const BLOCK_EXPLORER_TESTNET = {
ethereum: { title: "Etherscan", url: "https://sepolia.etherscan.io" },
bitcoin: { title: "Mempool Space", url: "https://mempool.space/testnet" },
}

const BLOCK_EXPLORER_MAINNET = {
ethereum: { title: "Etherscan", url: "https://etherscan.io" },
bitcoin: { title: "Blockstream", url: "https://blockstream.info" },
bitcoin: { title: "Mempool Space", url: "https://mempool.space" },
}

export const BLOCK_EXPLORER: Record<Chain, { title: string; url: string }> =
import.meta.env.VITE_USE_TESTNET === "true"
? BLOCK_EXPLORER_TESTNET
: BLOCK_EXPLORER_MAINNET

export const ETHEREUM_NETWORK: EthereumNetwork =
import.meta.env.VITE_USE_TESTNET === "true" ? "sepolia" : "mainnet"

Expand Down
504 changes: 154 additions & 350 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion sdk/babel.config.js

This file was deleted.

6 changes: 5 additions & 1 deletion sdk/jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export default {
import type { JestConfigWithTsJest } from "ts-jest"

const jestConfig: JestConfigWithTsJest = {
preset: "ts-jest",
testPathIgnorePatterns: ["<rootDir>/dist/", "<rootDir>/node_modules/"],
}

export default jestConfig
1 change: 0 additions & 1 deletion sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"test": "jest --verbose"
},
"devDependencies": {
"@babel/preset-env": "^7.23.7",
"@thesis-co/eslint-config": "github:thesis/eslint-config#7b9bc8c",
"@types/jest": "^29.5.11",
"@types/node": "^20.9.4",
Expand Down
3 changes: 2 additions & 1 deletion solidity/contracts/BitcoinDepositor.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
Expand Down Expand Up @@ -95,6 +95,7 @@ contract BitcoinDepositor is AbstractTBTCDepositor, Ownable2StepUpgradeable {
/// event emitted in the same transaction.
/// @param depositKey Deposit key identifying the deposit.
/// @param caller Address that finalized the deposit.
/// @param referral Data used for referral program.
/// @param initialAmount Amount of funding transaction.
/// @param bridgedAmount Amount of tBTC tokens that was bridged by the tBTC bridge.
/// @param depositorFee Depositor fee amount.
Expand Down
15 changes: 11 additions & 4 deletions solidity/contracts/BitcoinRedeemer.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";

Expand Down Expand Up @@ -52,7 +52,7 @@ contract BitcoinRedeemer is Ownable2StepUpgradeable, IReceiveApproval {
/// Attempted to call receiveApproval with empty data.
error EmptyExtraData();

/// Attempted to call redeemSharesAndUnmint with unexpected tBTC token owner.
/// Attempted to call _redeemSharesAndUnmint with unexpected tBTC token owner.
error UnexpectedTbtcTokenOwner();

/// Reverts if the redeemer is not the deposit owner.
Expand All @@ -61,6 +61,9 @@ contract BitcoinRedeemer is Ownable2StepUpgradeable, IReceiveApproval {
/// Reverts when approveAndCall to tBTC contract fails.
error ApproveAndCallFailed();

/// Reverts if the new TBTCVault contract is not tBTC token owner.
error NotTbtcTokenOwner();

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
Expand Down Expand Up @@ -108,7 +111,7 @@ contract BitcoinRedeemer is Ownable2StepUpgradeable, IReceiveApproval {
if (msg.sender != address(stbtc)) revert CallerNotAllowed(msg.sender);
if (extraData.length == 0) revert EmptyExtraData();

redeemSharesAndUnmint(from, amount, extraData);
_redeemSharesAndUnmint(from, amount, extraData);
}

/// @notice Updates TBTCVault contract address.
Expand All @@ -118,6 +121,10 @@ contract BitcoinRedeemer is Ownable2StepUpgradeable, IReceiveApproval {
revert ZeroAddress();
}

if (newTbtcVault != tbtcToken.owner()) {
revert NotTbtcTokenOwner();
}

emit TbtcVaultUpdated(tbtcVault, newTbtcVault);

tbtcVault = newTbtcVault;
Expand All @@ -144,7 +151,7 @@ contract BitcoinRedeemer is Ownable2StepUpgradeable, IReceiveApproval {
/// @param tbtcRedemptionData Additional data required for the tBTC redemption.
/// See `redemptionData` parameter description of `Bridge.requestRedemption`
/// function.
function redeemSharesAndUnmint(
function _redeemSharesAndUnmint(
address owner,
uint256 shares,
bytes calldata tbtcRedemptionData
Expand Down
4 changes: 2 additions & 2 deletions solidity/contracts/MezoAllocator.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
Expand Down Expand Up @@ -205,7 +205,7 @@ contract MezoAllocator is IDispatcher, Ownable2StepUpgradeable {
tbtc.safeTransfer(address(stbtc), tbtc.balanceOf(address(this)));
}

/// @notice Updates the maintainer address.
/// @notice Adds a new maintainer address.
/// @param maintainerToAdd Address of the new maintainer.
function addMaintainer(address maintainerToAdd) external onlyOwner {
if (maintainerToAdd == address(0)) {
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/PausableOwnable.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/bridge/ITBTCToken.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

/// @title Interface of TBTC token contract.
/// @notice This interface defines functions of TBTC token contract used by Acre
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/interfaces/IDispatcher.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

/// @title IDispatcher
/// @notice Interface for the Dispatcher contract.
Expand Down
13 changes: 11 additions & 2 deletions solidity/contracts/lib/ERC4626Fees.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// Inspired by https://docs.openzeppelin.com/contracts/5.x/erc4626#fees

pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC4626Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol";
Expand All @@ -13,10 +13,19 @@ import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
abstract contract ERC4626Fees is ERC4626Upgradeable {
using Math for uint256;

uint256 private constant _BASIS_POINT_SCALE = 1e4;
uint256 internal constant _BASIS_POINT_SCALE = 1e4;

// === Overrides ===

/// @dev Calculate the maximum amount of assets that can be withdrawn
/// by an account including fees. See {IERC4626-maxWithdraw}.
function maxWithdraw(
address account
) public view virtual override returns (uint256) {
uint256 maxAssets = super.maxWithdraw(account);
return maxAssets - _feeOnTotal(maxAssets, _exitFeeBasisPoints());
}

/// @dev Preview taking an entry fee on deposit. See {IERC4626-previewDeposit}.
function previewDeposit(
uint256 assets
Expand Down
61 changes: 30 additions & 31 deletions solidity/contracts/stBTC.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

Expand Down Expand Up @@ -74,6 +74,9 @@ contract stBTC is ERC4626Fees, PausableOwnable {
/// Reverts if the address is disallowed.
error DisallowedAddress();

/// Reverts if the fee basis points exceed the maximum value.
error ExceedsMaxFeeBasisPoints();

/// Reverts if the treasury address is the same.
error SameTreasury();

Expand Down Expand Up @@ -160,6 +163,9 @@ contract stBTC is ERC4626Fees, PausableOwnable {
function updateEntryFeeBasisPoints(
uint256 newEntryFeeBasisPoints
) external onlyOwner {
if (newEntryFeeBasisPoints > _BASIS_POINT_SCALE) {
revert ExceedsMaxFeeBasisPoints();
}
entryFeeBasisPoints = newEntryFeeBasisPoints;

emit EntryFeeBasisPointsUpdated(newEntryFeeBasisPoints);
Expand All @@ -170,27 +176,26 @@ contract stBTC is ERC4626Fees, PausableOwnable {
function updateExitFeeBasisPoints(
uint256 newExitFeeBasisPoints
) external onlyOwner {
if (newExitFeeBasisPoints > _BASIS_POINT_SCALE) {
revert ExceedsMaxFeeBasisPoints();
}
exitFeeBasisPoints = newExitFeeBasisPoints;

emit ExitFeeBasisPointsUpdated(newExitFeeBasisPoints);
}

/// @notice Returns the total amount of assets held by the vault across all
/// allocations and this contract.
function totalAssets() public view override returns (uint256) {
return
IERC20(asset()).balanceOf(address(this)) + dispatcher.totalAssets();
}

/// @notice Calls `receiveApproval` function on spender previously approving
/// the spender to withdraw from the caller multiple times, up to
/// the `amount` amount. If this function is called again, it
/// overwrites the current allowance with `amount`. Reverts if the
/// the `value` amount. If this function is called again, it
/// overwrites the current allowance with `value`. Reverts if the
/// approval reverted or if `receiveApproval` call on the spender
/// reverted.
/// @return True if both approval and `receiveApproval` calls succeeded.
/// @dev If the `amount` is set to `type(uint256).max` then
/// @dev If the `value` is set to `type(uint256).max` then
/// `transferFrom` and `burnFrom` will not reduce an allowance.
/// @param spender The address which will spend the funds.
/// @param value The amount of tokens to be spent.
/// @param extraData Additional data.
/// @return True if both approval and `receiveApproval` calls succeeded.
function approveAndCall(
address spender,
uint256 value,
Expand Down Expand Up @@ -295,6 +300,13 @@ contract stBTC is ERC4626Fees, PausableOwnable {
return super.redeem(shares, receiver, owner);
}

/// @notice Returns the total amount of assets held by the vault across all
/// allocations and this contract.
function totalAssets() public view override returns (uint256) {
return
IERC20(asset()).balanceOf(address(this)) + dispatcher.totalAssets();
}

/// @dev Returns the maximum amount of the underlying asset that can be
/// deposited into the Vault for the receiver, through a deposit call.
/// If the Vault is paused, returns 0.
Expand Down Expand Up @@ -335,29 +347,16 @@ contract stBTC is ERC4626Fees, PausableOwnable {
return super.maxRedeem(owner);
}

/// @notice Returns value of assets that would be exchanged for the amount of
/// shares owned by the `account`.
/// @param account Owner of shares.
/// @return Assets amount.
/// @notice Returns the number of assets that corresponds to the amount of
/// shares held by the specified account.
/// @dev This function is used to convert shares to assets position for
/// the given account. It does not take fees into account.
/// @param account The owner of the shares.
/// @return The amount of assets.
function assetsBalanceOf(address account) public view returns (uint256) {
return convertToAssets(balanceOf(account));
}

/// @dev Transfers a `value` amount of tokens from `from` to `to`, or
/// alternatively mints (or burns) if `from` (or `to`) is the zero
/// address. All customizations to transfers, mints, and burns should
/// be done by overriding this function.
/// @param from Sender of tokens.
/// @param to Receiver of tokens.
/// @param value Amount of tokens to transfer.
function _update(
address from,
address to,
uint256 value
) internal override whenNotPaused {
super._update(from, to, value);
}

/// @return Returns entry fee basis point used in deposits.
function _entryFeeBasisPoints() internal view override returns (uint256) {
return entryFeeBasisPoints;
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/test/BitcoinDepositorHarness.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
/* solhint-disable func-name-mixedcase */
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import {BitcoinDepositor} from "../BitcoinDepositor.sol";
import {MockBridge, MockTBTCVault} from "@keep-network/tbtc-v2/contracts/test/TestTBTCDepositor.sol";
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/test/MezoPortalStub.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/test/TestERC20.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/test/TestTBTC.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "../bridge/ITBTCToken.sol";
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/test/upgrades/BitcoinDepositorV2.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/test/upgrades/MezoAllocatorV2.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/test/upgrades/stBTCV2.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
pragma solidity 0.8.24;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

Expand Down
3 changes: 2 additions & 1 deletion solidity/contracts/utils/Errors.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.21;
pragma solidity 0.8.24;

/// @notice Reverts if a checked address is zero. Used by various contracts.
error ZeroAddress();
2 changes: 1 addition & 1 deletion solidity/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const config: HardhatUserConfig = {
solidity: {
compilers: [
{
version: "0.8.21",
version: "0.8.24",
settings: {
optimizer: {
enabled: true,
Expand Down
2 changes: 1 addition & 1 deletion solidity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"dotenv-safer": "^1.0.0",
"eslint": "^8.54.0",
"ethers": "^6.8.1",
"hardhat": "^2.19.1",
"hardhat": "^2.22.3",
"hardhat-contract-sizer": "^2.10.0",
"hardhat-deploy": "^0.11.43",
"hardhat-gas-reporter": "^1.0.9",
Expand Down
12 changes: 11 additions & 1 deletion solidity/test/BitcoinRedeemer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,14 +442,24 @@ describe("BitcoinRedeemer", () => {
})
})

context("when a new treasury is an allowed address", () => {
context("when a new tbtc vault is not tBTC token owner", () => {
it("should revert", async () => {
const newTbtcVault = await ethers.Wallet.createRandom().getAddress()
await expect(
bitcoinRedeemer.connect(governance).updateTbtcVault(newTbtcVault),
).to.be.revertedWithCustomError(bitcoinRedeemer, "NotTbtcTokenOwner")
})
})

context("when a new tbtc vault is an allowed address", () => {
let oldTbtcVault: string
let newTbtcVault: string
let tx: ContractTransactionResponse

before(async () => {
oldTbtcVault = await bitcoinRedeemer.tbtcVault()
newTbtcVault = await ethers.Wallet.createRandom().getAddress()
await tbtc.setOwner(newTbtcVault)

tx = await bitcoinRedeemer
.connect(governance)
Expand Down
Loading

0 comments on commit 76f4794

Please sign in to comment.