-
Notifications
You must be signed in to change notification settings - Fork 12
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
Sdai adapter and substream #102
Open
mp-web3
wants to merge
75
commits into
main
Choose a base branch
from
sdai-adapter-and-substream
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 69 commits
Commits
Show all changes
75 commits
Select commit
Hold shift + click to select a range
53ef2a0
repo setup
mp-web3 b64b4fd
Initialized tests
mp-web3 c51a089
feat: getTokens function
mp-web3 25bb3ef
feat: implemented getPoolIds function
mp-web3 f31ccc0
feat: implemented getLimits function
mp-web3 ee40c1a
feat: implemented checkInputTokens modifier, swap function, sell func…
mp-web3 de19314
test and fix: implemented testSwapFuzzDaiForSDai and fixed sell and b…
mp-web3 55a2668
test and fix: implemented testSwapFuzzSDaiForDai, fixed sell and buy …
mp-web3 d95f31a
feat: implementing getPriceSwapAt function
mp-web3 b496753
tests: implemented new tests
mp-web3 3057903
tests: ready for review
mp-web3 f7e94a6
fix: fixed functions order, entered comments, updated manifest.yaml file
mp-web3 956f969
review and fix
mp-web3 2ddf310
chore: Removed unused comments
mp-web3 6aa6a5b
fix: fixed getPriceAt(buyToken)
mp-web3 cd6e75e
fix of fix: deleted getPriceAt(buyToken), only need sellToken for the…
mp-web3 79486a9
fix: propeller review fixes
mp-web3 8bf2274
feat: Initial Setup
1f4fac5
chore: Initial tokens addition
28eaf8e
feat: Integrated sDAI substream
acee96c
fix: Fixed naming in deposit event
7f25064
feat: Updated modules with configurable params
b68a8a4
feat: Added sdai into cargo files
16b4311
fix: Fixed CI/CD errors
9eded50
fix: Fixed balancer error
9134f73
chore: Updated toml dependencies
1201499
fix: Fixed CI checks
6aa9c40
alignment with propeller main
mp-web3 e700fff
Update forge-std submodule reference to include ds-test
mp-web3 089a4c8
repo setup
mp-web3 0bce026
Initialized tests
mp-web3 5b0204c
feat: getTokens function
mp-web3 3e62843
feat: implemented getPoolIds function
mp-web3 c222887
feat: implemented getLimits function
mp-web3 7b04a72
feat: implemented checkInputTokens modifier, swap function, sell func…
mp-web3 144f7d3
test and fix: implemented testSwapFuzzDaiForSDai and fixed sell and b…
mp-web3 c7aaa59
test and fix: implemented testSwapFuzzSDaiForDai, fixed sell and buy …
mp-web3 6dc5eae
feat: implementing getPriceSwapAt function
mp-web3 d70ce84
tests: implemented new tests
mp-web3 5499156
tests: ready for review
mp-web3 a84cf6e
fix: fixed functions order, entered comments, updated manifest.yaml file
mp-web3 1edf12e
review and fix
mp-web3 3bd4584
chore: Removed unused comments
mp-web3 37eca48
fix: fixed getPriceAt(buyToken)
mp-web3 bdb8368
fix of fix: deleted getPriceAt(buyToken), only need sellToken for the…
mp-web3 cb21eb0
fix: propeller review fixes
mp-web3 2e49ad9
rebased propeller/main
mp-web3 d519a4e
Merge propeller/main into origin/main to include the latest updates
mp-web3 33abc5f
align with propeller main
mp-web3 c1e8c5f
Merge remote-tracking branch 'origin/main' into feature/MakerDAO-sDAI…
mp-web3 1db1509
mod
mp-web3 6bdee6a
aligned
mp-web3 92fb797
integration: integrated with adapter sdk
mp-web3 fec555c
Merge branch 'main' into sdai-adapter-sdk-integration
mp-web3 8edc192
Merge branch 'main' into feature/sdai-substream
mp-web3 ebf51fa
deleted cargo.lock because of conflicts
mp-web3 7d8ab1c
Merge pull request #3 from ShadowyCreators/sdai-adapter-sdk-integration
mp-web3 76755eb
commented testPoolBehaviourSDAI() because the test is currently broke…
mp-web3 be3ab7f
starting sdk integration
mp-web3 67a3d84
fix: fixed map_components
mp-web3 048a846
fix: sdai substream
mp-web3 d0caec1
update substream.yaml and creation integration_test
mp-web3 c7048ac
cargo.toml and rust-toolchain.toml update
mp-web3 b9d25f3
chore: working on integration test
mp-web3 0ec28ec
change stop_block
mp-web3 628cd92
clean up
mp-web3 629ca7d
fix component vault creation !call.call.state_reverted && is_deployme…
mp-web3 3880c6e
fixed map_components module as for comments in pull request
mp-web3 29fb2e1
fix: fix getLimits sDai
mp-web3 a1784b0
fix: fixed stop block integration test
mp-web3 b758f64
Merge pull request #4 from ShadowyCreators/sdk-implementation/sdai-ad…
mp-web3 8a04998
Merge remote-tracking branch 'shadowy/main' into sdai-adapter-and-sub…
mp-web3 17145cd
forge format
mp-web3 be7803b
cargo fmt
mp-web3 a8128bb
nightly build
mp-web3 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
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 |
---|---|---|
|
@@ -17,3 +17,8 @@ docs/ | |
# Others | ||
.DS_STORE | ||
lcov.info | ||
|
||
# lib | ||
lib/ | ||
|
||
InternalFunctions.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,37 @@ | ||
# information about the author helps us reach out in case of issues. | ||
author: | ||
name: shadowycoders.dev | ||
email: [email protected] | ||
|
||
# Protocol Constants | ||
constants: | ||
protocol_gas: 30000 | ||
# minimum capabilities we can expect, individual pools may extend these | ||
capabilities: | ||
- SellSide | ||
- BuySide | ||
- PriceFunction | ||
|
||
# The file containing the adapter contract | ||
contract: sDaiSwapAdapter.sol | ||
|
||
# Deployment instances used to generate chain specific bytecode. | ||
instances: | ||
- chain: | ||
name: mainnet | ||
id: 1 | ||
arguments: | ||
- "0x83F20F44975D03b1b09e64809B757c47f942BEeA" | ||
- "0x6B175474E89094C44Da98b954EedeAC495271d0F" | ||
|
||
# Specify some automatic test cases in case getPoolIds and | ||
# getTokens are not implemented. | ||
tests: | ||
instances: | ||
- pool_id: "0x83F20F44975D03b1b09e64809B757c47f942BEeA" | ||
sell_token: "0x6B175474E89094C44Da98b954EedeAC495271d0F" | ||
buy_token: "0x83F20F44975D03b1b09e64809B757c47f942BEeA" | ||
block: 19866715 | ||
chain: | ||
id: 1 | ||
name: mainnet |
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,236 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-or-later | ||
pragma solidity ^0.8.13; | ||
|
||
import {ISwapAdapter} from "src/interfaces/ISwapAdapter.sol"; | ||
import {IERC20Metadata} from "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; | ||
import {IERC20, SafeERC20} from "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; | ||
|
||
/// @title sDaiSwapAdapter | ||
|
||
contract sDaiSwapAdapter is ISwapAdapter { | ||
using SafeERC20 for IERC20; | ||
using SafeERC20 for ISavingsDai; | ||
|
||
uint256 constant PRECISE_UNIT = 10 ** 18; | ||
|
||
ISavingsDai immutable savingsDai; | ||
IERC20 immutable dai; | ||
|
||
constructor(address savingsDai_, address dai_) { | ||
savingsDai = ISavingsDai(savingsDai_); | ||
dai = IERC20(dai_); | ||
} | ||
|
||
/// @dev Check if swap between provided sellToken and buyToken are supported | ||
/// by this adapter | ||
modifier checkInputTokens(address sellToken, address buyToken) { | ||
if ( | ||
(sellToken == address(dai) && buyToken == address(savingsDai)) || | ||
(sellToken == address(savingsDai) && buyToken == address(dai)) | ||
) {} else { | ||
revert Unavailable("This pool only supports DAI<->sDAI swaps"); | ||
} | ||
|
||
_; | ||
} | ||
|
||
/// @inheritdoc ISwapAdapter | ||
/// @notice price doesn't change in the same block after swap for any given quantity | ||
function price( | ||
bytes32, | ||
address sellToken, | ||
address buyToken, | ||
uint256[] memory specifiedAmounts | ||
) | ||
external | ||
view | ||
override | ||
checkInputTokens(sellToken, buyToken) | ||
returns (Fraction[] memory prices) | ||
{ | ||
prices = new Fraction[](specifiedAmounts.length); | ||
|
||
Fraction memory outputPrice = getPriceAt(sellToken); | ||
|
||
for (uint256 i = 0; i < specifiedAmounts.length; i++) { | ||
prices[i] = outputPrice; | ||
} | ||
} | ||
|
||
/// @inheritdoc ISwapAdapter | ||
function swap( | ||
bytes32, | ||
address sellToken, | ||
address buyToken, | ||
OrderSide side, | ||
uint256 specifiedAmount | ||
) | ||
external | ||
override | ||
checkInputTokens(sellToken, buyToken) | ||
returns (Trade memory trade) | ||
{ | ||
if (specifiedAmount == 0) { | ||
return trade; | ||
} | ||
uint256 gasBefore = gasleft(); | ||
if (side == OrderSide.Sell) { | ||
trade.calculatedAmount = sell(IERC20(sellToken), specifiedAmount); | ||
} else { | ||
trade.calculatedAmount = buy(IERC20(buyToken), specifiedAmount); | ||
} | ||
|
||
trade.gasUsed = gasBefore - gasleft(); | ||
|
||
trade.price = getPriceAt(sellToken); | ||
} | ||
|
||
/// @inheritdoc ISwapAdapter | ||
function getLimits( | ||
bytes32, | ||
address sellToken, | ||
address | ||
) external view override returns (uint256[] memory limits) { | ||
limits = new uint256[](2); | ||
|
||
if (sellToken == address(dai)) { | ||
limits[0] = 3 * (10 ** 24); | ||
limits[1] = limits[0]; | ||
} else { | ||
uint256 totalAssets = savingsDai.totalAssets(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kayibal I think this is not possible with the current Simulation module, as we override the tokens, right? |
||
limits[0] = savingsDai.previewWithdraw(totalAssets); | ||
limits[1] = totalAssets; | ||
} | ||
} | ||
|
||
/// @inheritdoc ISwapAdapter | ||
function getCapabilities( | ||
bytes32, | ||
address, | ||
address | ||
) external pure override returns (Capability[] memory capabilities) { | ||
capabilities = new Capability[](4); | ||
capabilities[0] = Capability.SellOrder; | ||
capabilities[1] = Capability.BuyOrder; | ||
capabilities[2] = Capability.PriceFunction; | ||
capabilities[3] = Capability.ConstantPrice; | ||
} | ||
|
||
/// @inheritdoc ISwapAdapter | ||
function getTokens( | ||
bytes32 | ||
) external view override returns (address[] memory tokens) { | ||
tokens = new address[](2); | ||
tokens[0] = address(dai); | ||
tokens[1] = address(savingsDai); | ||
} | ||
|
||
/// @inheritdoc ISwapAdapter | ||
function getPoolIds( | ||
uint256, | ||
uint256 | ||
) external view override returns (bytes32[] memory ids) { | ||
ids = new bytes32[](1); | ||
ids[0] = bytes20(address(savingsDai)); | ||
} | ||
|
||
/// @notice Executes a sell order on the contract. | ||
/// @param sellToken The token being sold. | ||
/// @param amount The amount to be traded. | ||
/// @return calculatedAmount The amount of tokens received. | ||
function sell( | ||
IERC20 sellToken, | ||
uint256 amount | ||
) internal returns (uint256 calculatedAmount) { | ||
sellToken.safeTransferFrom(msg.sender, address(this), amount); | ||
|
||
if (address(sellToken) == address(dai)) { | ||
sellToken.safeIncreaseAllowance(address(savingsDai), amount); | ||
} | ||
|
||
return | ||
address(sellToken) == address(dai) | ||
? savingsDai.deposit(amount, msg.sender) | ||
: savingsDai.redeem(amount, msg.sender, address(this)); | ||
} | ||
|
||
/// @notice Executes a buy order on the contract. | ||
/// @param buyToken The token being bought. | ||
/// @param amount The amount of buyToken to receive. | ||
/// @return calculatedAmount The amount of sellToken sold. | ||
function buy( | ||
IERC20 buyToken, | ||
uint256 amount | ||
) internal returns (uint256 calculatedAmount) { | ||
if (address(buyToken) == address(savingsDai)) { | ||
// DAI-sDAI | ||
uint256 amountIn = savingsDai.previewMint(amount); | ||
dai.safeTransferFrom(msg.sender, address(this), amountIn); | ||
dai.safeIncreaseAllowance(address(savingsDai), amountIn); | ||
return savingsDai.mint(amount, msg.sender); | ||
} else { | ||
// sDAI-DAI | ||
uint256 amountIn = savingsDai.previewWithdraw(amount); | ||
savingsDai.safeTransferFrom(msg.sender, address(this), amountIn); | ||
return savingsDai.withdraw(amount, msg.sender, address(this)); | ||
} | ||
} | ||
|
||
/// @notice Get swap price | ||
/// @param sellToken token to sell | ||
function getPriceAt( | ||
address sellToken | ||
) internal view returns (Fraction memory) { | ||
if (sellToken == address(dai)) { | ||
return | ||
Fraction(savingsDai.previewDeposit(PRECISE_UNIT), PRECISE_UNIT); | ||
} else { | ||
return | ||
Fraction(savingsDai.previewRedeem(PRECISE_UNIT), PRECISE_UNIT); | ||
} | ||
} | ||
} | ||
|
||
interface ISavingsDai is IERC20 { | ||
function asset() external view returns (address); | ||
|
||
function decimals() external view returns (uint8); | ||
|
||
function maxMint(address) external pure returns (uint256); | ||
|
||
function maxRedeem(address) external view returns (uint256); | ||
|
||
function previewMint(uint256 shares) external view returns (uint256); | ||
|
||
function previewWithdraw(uint256 assets) external view returns (uint256); | ||
|
||
function previewDeposit(uint256 assets) external view returns (uint256); | ||
|
||
function previewRedeem(uint256 shares) external view returns (uint256); | ||
|
||
function totalAssets() external view returns (uint256); | ||
|
||
function totalSupply() external pure returns (uint256); | ||
|
||
function deposit( | ||
uint256 assets, | ||
address receiver | ||
) external returns (uint256 shares); | ||
|
||
function mint( | ||
uint256 shares, | ||
address receiver | ||
) external returns (uint256 assets); | ||
|
||
function withdraw( | ||
uint256 assets, | ||
address receiver, | ||
address owner | ||
) external returns (uint256 shares); | ||
|
||
function redeem( | ||
uint256 shares, | ||
address receiver, | ||
address owner | ||
) external returns (uint256 assets); | ||
} |
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.
Can you explain this value it seems very arbitrary.
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.
@kayibal It is the DAI total supply value approx., and we need to use static values due to the incompatibility issue between substreams and external calls
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.
We can overwrite the token's
totalSupply
so ideally we should track this via attributesCurrently, DAI supply is 1000 times bigger than this number.