Skip to content

Commit

Permalink
Merge branch 'dev-bc-v5' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
tpawn committed Dec 18, 2023
2 parents 14962b6 + 52fd778 commit a50b8a6
Show file tree
Hide file tree
Showing 15 changed files with 2,944 additions and 0 deletions.
1,043 changes: 1,043 additions & 0 deletions contracts/fund/FundV5.sol

Large diffs are not rendered by default.

505 changes: 505 additions & 0 deletions contracts/fund/PrimaryMarketV5.sol

Large diffs are not rendered by default.

64 changes: 64 additions & 0 deletions contracts/fund/WstETHPrimaryMarketRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.6.10 <0.8.0;
pragma experimental ABIEncoderV2;

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

import "../interfaces/IPrimaryMarketV5.sol";
import "../interfaces/IFundV3.sol";
import "../interfaces/IWstETH.sol";
import "../interfaces/ITrancheIndexV2.sol";

contract WstETHPrimaryMarketRouter is ITrancheIndexV2 {
using SafeERC20 for IERC20;

IPrimaryMarketV5 public immutable primaryMarket;
IFundV3 public immutable fund;
address private immutable _wstETH;
address private immutable _stETH;
address private immutable _tokenB;

constructor(address pm) public {
primaryMarket = IPrimaryMarketV5(pm);
IFundV3 fund_ = IFundV3(IPrimaryMarketV5(pm).fund());
fund = fund_;
_wstETH = fund_.tokenUnderlying();
_stETH = IWstETH(fund_.tokenUnderlying()).stETH();
_tokenB = fund_.tokenB();
}

function create(
address recipient,
bool isWrapped,
uint256 underlying,
uint256 minOutQ,
uint256 version
) public returns (uint256 outQ) {
if (isWrapped) {
IERC20(_stETH).safeTransferFrom(msg.sender, address(this), underlying);
underlying = IWstETH(_wstETH).wrap(underlying);
IERC20(_wstETH).safeTransfer(address(primaryMarket), underlying);
} else {
IERC20(_wstETH).safeTransferFrom(msg.sender, address(primaryMarket), underlying);
}

outQ = primaryMarket.create(recipient, minOutQ, version);
}

function createAndSplit(
uint256 underlying,
bool isWrapped,
uint256 minOutQ,
uint256 version
) external {
// Create QUEEN
uint256 outQ = create(address(this), isWrapped, underlying, minOutQ, version);

// Split QUEEN into BISHOP and ROOK
(uint256 outB, uint256 outR) = primaryMarket.split(address(this), outQ, version);

fund.trancheTransfer(TRANCHE_B, msg.sender, outB, version);
fund.trancheTransfer(TRANCHE_R, msg.sender, outR, version);
}
}
24 changes: 24 additions & 0 deletions contracts/governance/FeeConverter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.6.10 <0.8.0;

import "../interfaces/IFundV5.sol";
import "../interfaces/IPrimaryMarketV5.sol";
import "../interfaces/ITrancheIndexV2.sol";

contract FeeConverter is ITrancheIndexV2 {
IFundV5 public immutable fund;
IPrimaryMarketV5 public immutable primaryMarket;
address public immutable feeCollector;

constructor(address primaryMarket_, address feeCollector_) public {
primaryMarket = IPrimaryMarketV5(primaryMarket_);
fund = IFundV5(IPrimaryMarketV5(primaryMarket_).fund());
feeCollector = feeCollector_;
}

function collectFee() external {
uint256 fee = fund.trancheBalanceOf(TRANCHE_Q, address(this));
uint256 version = fund.getRebalanceSize();
primaryMarket.redeem(feeCollector, fee, 0, version);
}
}
14 changes: 14 additions & 0 deletions contracts/interfaces/IFundV5.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.6.10 <0.8.0;

import "./IFundV3.sol";

interface IFundV5 is IFundV3 {
function weightB() external view returns (uint256);

function getSettledDay() external view returns (uint256);

function getEquivalentTotalR() external view returns (uint256);

function frozen() external view returns (bool);
}
63 changes: 63 additions & 0 deletions contracts/interfaces/IPrimaryMarketV5.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.6.10 <0.8.0;

interface IPrimaryMarketV5 {
function fund() external view returns (address);

function getCreation(uint256 underlying) external view returns (uint256 outQ);

function getRedemption(uint256 inQ) external view returns (uint256 underlying, uint256 fee);

function getSplit(uint256 inQ) external view returns (uint256 outB, uint256 outQ);

function getMerge(uint256 inB) external view returns (uint256 inR, uint256 outQ, uint256 feeQ);

function canBeRemovedFromFund() external view returns (bool);

function create(
address recipient,
uint256 minOutQ,
uint256 version
) external returns (uint256 outQ);

function redeem(
address recipient,
uint256 inQ,
uint256 minUnderlying,
uint256 version
) external returns (uint256 underlying);

function redeemAndUnwrap(
address recipient,
uint256 inQ,
uint256 minUnderlying,
uint256 version
) external returns (uint256 underlying);

function queueRedemption(
address recipient,
uint256 inQ,
uint256 minUnderlying,
uint256 version
) external returns (uint256 underlying, uint256 index);

function claimRedemptions(
address account,
uint256[] calldata indices
) external returns (uint256 underlying);

function claimRedemptionsAndUnwrap(
address account,
uint256[] calldata indices
) external returns (uint256 underlying);

function split(
address recipient,
uint256 inQ,
uint256 version
) external returns (uint256 outB, uint256 outR);

function merge(address recipient, uint256 inB, uint256 version) external returns (uint256 outQ);

function settle(uint256 day) external;
}
16 changes: 16 additions & 0 deletions contracts/interfaces/IWstETH.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.6.10 <0.8.0;

interface IWstETH {
function stETH() external view returns (address);

function stEthPerToken() external view returns (uint256);

function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256);

function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256);

function wrap(uint256 _stETHAmount) external returns (uint256);

function unwrap(uint256 _wstETHAmount) external returns (uint256);
}
26 changes: 26 additions & 0 deletions contracts/oracle/ConstAprOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.6.10 <0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

import "../interfaces/IAprOracle.sol";

contract ConstAprOracle is IAprOracle, Ownable {
event Updated(uint256 dailyRate);

uint256 public dailyRate;

constructor(uint256 dailyRate_) public {
dailyRate = dailyRate_;
emit Updated(dailyRate_);
}

function update(uint256 newRate) external onlyOwner {
dailyRate = newRate;
emit Updated(newRate);
}

function capture() external override returns (uint256) {
return dailyRate;
}
}
25 changes: 25 additions & 0 deletions contracts/oracle/WstETHPriceOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.6.10 <0.8.0;

import "../interfaces/ITwapOracleV2.sol";
import "../interfaces/IWstETH.sol";

/// @title wstETH Price oracle
/// @author Tranchess
contract WstETHPriceOracle is ITwapOracleV2 {
IWstETH public immutable wstETH;

constructor(address wstETH_) public {
wstETH = IWstETH(wstETH_);
}

/// @notice Return the latest price with 18 decimal places.
function getLatest() external view override returns (uint256) {
return wstETH.stEthPerToken();
}

/// @notice Return the latest price with 18 decimal places.
function getTwap(uint256) external view override returns (uint256) {
return wstETH.stEthPerToken();
}
}
Loading

0 comments on commit a50b8a6

Please sign in to comment.