-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(module): Notional Trade Module (#251)
- Loading branch information
Showing
28 changed files
with
3,691 additions
and
34 deletions.
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
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,68 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
pragma solidity 0.6.10; | ||
pragma experimental "ABIEncoderV2"; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
|
||
/// @notice Different types of internal tokens | ||
/// - UnderlyingToken: underlying asset for a cToken (except for Ether) | ||
/// - cToken: Compound interest bearing token | ||
/// - cETH: Special handling for cETH tokens | ||
/// - Ether: the one and only | ||
/// - NonMintable: tokens that do not have an underlying (therefore not cTokens) | ||
enum TokenType { | ||
UnderlyingToken, | ||
cToken, | ||
cETH, | ||
Ether, | ||
NonMintable | ||
} | ||
|
||
interface IWrappedfCash { | ||
function initialize(uint16 currencyId, uint40 maturity) external; | ||
|
||
/// @notice Mints wrapped fCash ERC20 tokens | ||
function mintViaAsset( | ||
uint256 depositAmountExternal, | ||
uint88 fCashAmount, | ||
address receiver, | ||
uint32 minImpliedRate | ||
) external; | ||
|
||
function mintViaUnderlying( | ||
uint256 depositAmountExternal, | ||
uint88 fCashAmount, | ||
address receiver, | ||
uint32 minImpliedRate | ||
) external; | ||
|
||
function redeemToAsset(uint256 amount, address receiver, uint32 maxImpliedRate) external; | ||
function redeemToUnderlying(uint256 amount, address receiver, uint32 maxImpliedRate) external; | ||
|
||
/// @notice Returns the underlying fCash ID of the token | ||
function getfCashId() external view returns (uint256); | ||
|
||
/// @notice True if the fCash has matured, assets mature exactly on the block time | ||
function hasMatured() external view returns (bool); | ||
|
||
/// @notice Returns the components of the fCash idd | ||
function getDecodedID() external view returns (uint16 currencyId, uint40 maturity); | ||
|
||
/// @notice Returns the current market index for this fCash asset. If this returns | ||
/// zero that means it is idiosyncratic and cannot be traded. | ||
function getMarketIndex() external view returns (uint8); | ||
|
||
/// @notice Returns the token and precision of the token that this token settles | ||
/// to. For example, fUSDC will return the USDC token address and 1e6. The zero | ||
/// address will represent ETH. | ||
function getUnderlyingToken() external view returns (IERC20 underlyingToken, int256 underlyingPrecision); | ||
|
||
/// @notice Returns the asset token which the fCash settles to. This will be an interest | ||
/// bearing token like a cToken or aToken. | ||
function getAssetToken() external view returns (IERC20 assetToken, int256 assetPrecision, TokenType tokenType); | ||
|
||
function getToken(bool useUnderlying) external view returns (IERC20 token, bool isETH); | ||
} | ||
|
||
|
||
interface IWrappedfCashComplete is IWrappedfCash, IERC20 {} |
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,9 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
pragma solidity 0.6.10; | ||
|
||
interface IWrappedfCashFactory { | ||
function deployWrapper(uint16 currencyId, uint40 maturity) external returns(address); | ||
function computeAddress(uint16 currencyId, uint40 maturity) external view returns(address); | ||
} | ||
|
||
|
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,5 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.11; | ||
import { NotionalProxy } from "notional-solidity-sdk/interfaces/notional/NotionalProxy.sol"; | ||
|
||
interface INotionalProxy is NotionalProxy {} |
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,50 @@ | ||
/* | ||
Copyright 2022 Set Labs Inc. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
SPDX-License-Identifier: Apache License, Version 2.0 | ||
*/ | ||
|
||
pragma solidity 0.6.10; | ||
pragma experimental "ABIEncoderV2"; | ||
|
||
import { IWrappedfCashFactory } from "../interfaces/IWrappedFCashFactory.sol"; | ||
import { WrappedfCashMock } from "./WrappedfCashMock.sol"; | ||
|
||
|
||
// mock class using BasicToken | ||
contract WrappedfCashFactoryMock is IWrappedfCashFactory { | ||
|
||
mapping(uint16 => mapping(uint40 => address)) paramsToAddress; | ||
bool private revertComputeAddress; | ||
|
||
function registerWrapper(uint16 _currencyId, uint40 _maturity, address _fCashWrapper) external { | ||
paramsToAddress[_currencyId][_maturity] = _fCashWrapper; | ||
} | ||
|
||
function deployWrapper(uint16 _currencyId, uint40 _maturity) external override returns(address) { | ||
return computeAddress(_currencyId, _maturity); | ||
} | ||
|
||
function computeAddress(uint16 _currencyId, uint40 _maturity) public view override returns(address) { | ||
require(!revertComputeAddress, "Test revertion ComputeAddress"); | ||
return paramsToAddress[_currencyId][_maturity]; | ||
} | ||
|
||
function setRevertComputeAddress(bool _revertComputeAddress) external{ | ||
revertComputeAddress = _revertComputeAddress; | ||
} | ||
|
||
|
||
} |
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,175 @@ | ||
/* | ||
Copyright 2022 Set Labs Inc. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
SPDX-License-Identifier: Apache License, Version 2.0 | ||
*/ | ||
|
||
pragma solidity 0.6.10; | ||
pragma experimental "ABIEncoderV2"; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import { TokenType, IWrappedfCash } from "../interfaces/IWrappedFCash.sol"; | ||
|
||
// mock class using BasicToken | ||
contract WrappedfCashMock is ERC20, IWrappedfCash { | ||
|
||
uint256 private fCashId; | ||
uint40 private maturity; | ||
bool private matured; | ||
uint16 private currencyId; | ||
uint8 private marketIndex; | ||
IERC20 private underlyingToken; | ||
int256 private underlyingPrecision; | ||
IERC20 private assetToken; | ||
int256 private assetPrecision; | ||
TokenType private tokenType; | ||
|
||
IERC20 private weth; | ||
|
||
bool private revertDecodedID; | ||
|
||
uint256 public redeemTokenReturned; | ||
uint256 public mintTokenSpent; | ||
|
||
address internal constant ETH_ADDRESS = address(0); | ||
|
||
constructor (IERC20 _assetToken, IERC20 _underlyingToken, IERC20 _weth) public ERC20("FCashMock", "FCM") { | ||
assetToken = _assetToken; | ||
underlyingToken = _underlyingToken; | ||
weth = _weth; | ||
} | ||
|
||
function initialize(uint16 _currencyId, uint40 _maturity) external override { | ||
currencyId = _currencyId; | ||
maturity = _maturity; | ||
} | ||
|
||
/// @notice Mints wrapped fCash ERC20 tokens | ||
function mintViaAsset( | ||
uint256 depositAmountExternal, | ||
uint88 fCashAmount, | ||
address receiver, | ||
uint32 /* minImpliedRate */ | ||
) external override{ | ||
uint256 assetTokenAmount = mintTokenSpent == 0 ? depositAmountExternal : mintTokenSpent; | ||
require(assetToken.transferFrom(msg.sender, address(this), assetTokenAmount), "WrappedfCashMock: Transfer failed"); | ||
_mint(receiver, fCashAmount); | ||
} | ||
|
||
function mintViaUnderlying( | ||
uint256 depositAmountExternal, | ||
uint88 fCashAmount, | ||
address receiver, | ||
uint32 /* minImpliedRate */ | ||
) external override{ | ||
uint256 underlyingTokenAmount = mintTokenSpent == 0 ? depositAmountExternal : mintTokenSpent; | ||
bool transferSuccess; | ||
if(address(underlyingToken) == ETH_ADDRESS) { | ||
transferSuccess = weth.transferFrom(msg.sender, address(this), underlyingTokenAmount); | ||
} else { | ||
transferSuccess = underlyingToken.transferFrom(msg.sender, address(this), underlyingTokenAmount); | ||
} | ||
require(transferSuccess, "WrappedfCashMock: Transfer failed"); | ||
_mint(receiver, fCashAmount); | ||
} | ||
|
||
|
||
function redeemToAsset( | ||
uint256 amount, | ||
address receiver, | ||
uint32 /* maxImpliedRate */ | ||
) external override { | ||
_burn(msg.sender, amount); | ||
uint256 assetTokenAmount = redeemTokenReturned == 0 ? amount : redeemTokenReturned; | ||
require(assetToken.transfer(receiver, assetTokenAmount), "WrappedfCashMock: Transfer failed"); | ||
} | ||
|
||
function redeemToUnderlying( | ||
uint256 amount, | ||
address receiver, | ||
uint32 /* maxImpliedRate */ | ||
) external override { | ||
_burn(msg.sender, amount); | ||
uint256 underlyingTokenAmount = redeemTokenReturned == 0 ? amount : redeemTokenReturned; | ||
if(address(underlyingToken) == ETH_ADDRESS) { | ||
weth.transfer(receiver, underlyingTokenAmount); | ||
} else { | ||
underlyingToken.transfer(receiver, underlyingTokenAmount); | ||
} | ||
} | ||
|
||
/// @notice Returns the underlying fCash ID of the token | ||
function getfCashId() external override view returns (uint256) { | ||
return fCashId; | ||
} | ||
|
||
/// @notice True if the fCash has matured, assets mature exactly on the block time | ||
function hasMatured() external override view returns (bool) { | ||
return matured; | ||
} | ||
|
||
/// @notice Returns the components of the fCash idd | ||
function getDecodedID() external override view returns (uint16, uint40) { | ||
require(!revertDecodedID, "Test revertion DecodedID"); | ||
return (currencyId, maturity); | ||
} | ||
|
||
/// @notice Returns the current market index for this fCash asset. If this returns | ||
/// zero that means it is idiosyncratic and cannot be traded. | ||
function getMarketIndex() external override view returns (uint8) { | ||
return marketIndex; | ||
} | ||
|
||
/// @notice Returns the token and precision of the token that this token settles | ||
/// to. For example, fUSDC will return the USDC token address and 1e6. The zero | ||
/// address will represent ETH. | ||
function getUnderlyingToken() public override view returns (IERC20, int256) { | ||
return (underlyingToken, underlyingPrecision); | ||
} | ||
|
||
/// @notice Returns the asset token which the fCash settles to. This will be an interest | ||
/// bearing token like a cToken or aToken. | ||
function getAssetToken() public override view returns (IERC20, int256, TokenType) { | ||
return (assetToken, assetPrecision, tokenType); | ||
} | ||
|
||
function setMatured(bool _matured) external{ | ||
matured = _matured; | ||
} | ||
|
||
function setRedeemTokenReturned(uint256 _redeemTokenReturned) external{ | ||
redeemTokenReturned = _redeemTokenReturned; | ||
} | ||
|
||
function setMintTokenSpent(uint256 _mintTokenSpent) external{ | ||
mintTokenSpent = _mintTokenSpent; | ||
} | ||
|
||
function setRevertDecodedID(bool _revertDecodedID) external{ | ||
revertDecodedID = _revertDecodedID; | ||
} | ||
|
||
function getToken(bool useUnderlying) public view override returns (IERC20 token, bool isETH) { | ||
if (useUnderlying) { | ||
(token, /* */) = getUnderlyingToken(); | ||
} else { | ||
(token, /* */, /* */) = getAssetToken(); | ||
} | ||
isETH = address(token) == ETH_ADDRESS; | ||
} | ||
|
||
|
||
} |
10 changes: 10 additions & 0 deletions
10
contracts/protocol/integration/wrap/notional/WrappedfCash.sol
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,10 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.11; | ||
import { wfCashERC4626 } from "wrapped-fcash/contracts/wfCashERC4626.sol"; | ||
import { INotionalV2 } from "wrapped-fcash/interfaces/notional/INotionalV2.sol"; | ||
import { IWETH9 } from "wrapped-fcash/interfaces/IWETH9.sol"; | ||
|
||
contract WrappedfCash is wfCashERC4626 { | ||
constructor(INotionalV2 _notionalProxy, IWETH9 _weth) wfCashERC4626(_notionalProxy, _weth){ | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
contracts/protocol/integration/wrap/notional/WrappedfCashFactory.sol
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,8 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.11; | ||
import { WrappedfCashFactory as WrappedfCashFactoryBase } from "wrapped-fcash/contracts/proxy/WrappedfCashFactory.sol"; | ||
|
||
contract WrappedfCashFactory is WrappedfCashFactoryBase { | ||
constructor(address _beacon) WrappedfCashFactoryBase(_beacon){ | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
contracts/protocol/integration/wrap/notional/nBeaconProxy.sol
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,7 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.11; | ||
import { nBeaconProxy as nBeaconProxyBase } from "wrapped-fcash/contracts/proxy/nBeaconProxy.sol"; | ||
|
||
contract nBeaconProxy is nBeaconProxyBase { | ||
constructor(address beacon, bytes memory data) payable nBeaconProxyBase(beacon, data) { } | ||
} |
11 changes: 11 additions & 0 deletions
11
contracts/protocol/integration/wrap/notional/nUpgradeableBeacon.sol
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,11 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.11; | ||
|
||
import "openzeppelin-contracts-V4/proxy/beacon/UpgradeableBeacon.sol"; | ||
|
||
/// @dev Re-exporting to make available to brownie | ||
/// UpgradeableBeacon is Ownable, default owner is the deployer | ||
contract nUpgradeableBeacon is UpgradeableBeacon { | ||
constructor(address implementation_) UpgradeableBeacon(implementation_) {} | ||
} | ||
|
Oops, something went wrong.