-
Notifications
You must be signed in to change notification settings - Fork 7
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
alternative implementation to use FL #109
Draft
adamskrodzki
wants to merge
8
commits into
develop
Choose a base branch
from
as/alternative_approach
base: develop
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.
Draft
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
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
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,18 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-or-later | ||
|
||
pragma solidity ^0.8.1; | ||
|
||
struct CdpData { | ||
address gemJoin; | ||
address payable fundsReceiver; | ||
uint256 cdpId; | ||
bytes32 ilk; | ||
uint256 requiredDebt; | ||
uint256 borrowCollateral; | ||
uint256 withdrawCollateral; | ||
uint256 withdrawDai; | ||
uint256 depositDai; | ||
uint256 depositCollateral; | ||
bool skipFL; | ||
string methodName; | ||
} |
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,103 @@ | ||
pragma solidity ^0.8.1; | ||
import "./interfaces/ExternalInterfaces.sol"; | ||
import "./../flash-mint/interface/IERC3156FlashBorrower.sol"; | ||
import "./../flash-mint/interface/IERC3156FlashLender.sol"; | ||
|
||
struct FlashLoanData { | ||
address lendedTokenAddress; | ||
uint256 lendedTokenAmount; | ||
} | ||
|
||
struct FlashLoanExecutionData { | ||
address caller; | ||
address token; | ||
uint256 amount; | ||
uint256 fee; | ||
} | ||
|
||
abstract contract BaseAction { | ||
function main(bytes calldata data, FlashLoanExecutionData memory executionData) external virtual; | ||
|
||
function beforeFlashLoan(bytes calldata data) external virtual returns (bytes memory); | ||
|
||
function afterFlashLoan(bytes calldata data) external virtual; | ||
|
||
function isFlashLoanRequired() external virtual returns (bool); | ||
} | ||
|
||
contract FlashLoanProvider is IERC3156FlashBorrower { | ||
address public immutable lender; | ||
address public immutable self; | ||
|
||
constructor(address _lender) { | ||
lender = _lender; | ||
self = address(this); | ||
} | ||
|
||
function onFlashLoan( | ||
address caller, | ||
address token, | ||
uint256 amount, | ||
uint256 fee, | ||
bytes calldata params | ||
) public override returns (bytes32) { | ||
(address action, bytes memory mainData) = abi.decode(params, (address, bytes)); | ||
BaseAction(action).main(mainData, FlashLoanExecutionData(caller, token, amount, fee)); //here we do not mind change context since we changed it anyway | ||
} | ||
|
||
function execute(address action, bytes memory actionsData) public { | ||
(FlashLoanData memory flashLoanData, bytes memory mainData) = abi.decode( | ||
actionsData, | ||
(FlashLoanData, bytes) | ||
); | ||
|
||
bytes memory beforeCallData = abi.encodeWithSignature("beforeFlashLoan(bytes)", mainData); | ||
(bool status, bytes memory step2Data) = address(action).delegatecall(beforeCallData); | ||
require(status, "action/beforeFlashLoan-failed"); | ||
|
||
IERC3156FlashLender(lender).flashLoan( | ||
IERC3156FlashBorrower(self), | ||
flashLoanData.lendedTokenAddress, | ||
flashLoanData.lendedTokenAmount, | ||
abi.encode(action, step2Data) | ||
); | ||
|
||
bytes memory afterCallData = abi.encodeWithSignature("afterFlashLoan(bytes)", mainData); | ||
(status, ) = address(action).delegatecall(afterCallData); | ||
require(status, "action/afterFlashLoan-failed"); | ||
} | ||
} | ||
|
||
contract Runner { | ||
ServiceRegistryLike public immutable registry; | ||
FlashLoanProvider public immutable flashLoanProvider; | ||
|
||
constructor(address _reg, address _flProvider) { | ||
registry = ServiceRegistryLike(_reg); | ||
flashLoanProvider = FlashLoanProvider(_flProvider); | ||
} | ||
|
||
/* | ||
actionName - key for stored in serviceRegistry address of action implementation, for example MCLOSE_TO_DAI, GCLOSE_TO_DAI | ||
actionData - abi.encode(flashLoanData, mainData) | ||
where flashLoanData are information for flash loan about asset and amount to borrow | ||
where mainData is action-specific bytes used in beforeFlashLoan, main, afterFlashLoan that then Adtion internally decodes to whatever it uses | ||
*/ | ||
function executeAction(string calldata actionName, bytes calldata actionData) external { | ||
BaseAction action = BaseAction(registry.getRegisteredService(actionName)); | ||
|
||
bool useFlashLoan = action.isFlashLoanRequired(); | ||
if (useFlashLoan) { | ||
bytes memory flashLoanCallData = abi.encodeWithSignature( | ||
"execute(address,bytes)", | ||
abi.encode(address(action), actionData) | ||
); | ||
(bool status, ) = address(flashLoanProvider).delegatecall(flashLoanCallData); | ||
require(status, "runner/flashloan-failed"); | ||
} else { | ||
bytes memory actionDelegateData = abi.encodeWithSignature("main(bytes)", actionData); | ||
(bool status, ) = address(action).delegatecall(actionDelegateData); | ||
require(status, "runner/action-failed"); | ||
} | ||
} | ||
} |
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,66 @@ | ||
pragma solidity ^0.8.1; | ||
import "./../utils/SafeMath.sol"; | ||
import "./../interfaces/IERC20.sol"; | ||
import "./../interfaces/mcd/IVat.sol"; | ||
import "./../interfaces/mcd/IManager.sol"; | ||
import "./../interfaces/mcd/IJoin.sol"; | ||
|
||
//TODO: This should be library "using MakerMath for uint256" | ||
//TODO: Get rid of SafeMath since new compiler do safeMath out of the box | ||
contract MakerMath { | ||
using SafeMath for uint256; | ||
|
||
function convertTo18(address gemJoin, uint256 amt) internal view returns (uint256 wad) { | ||
// For those collaterals that have less than 18 decimals precision we need to do the conversion before passing to frob function | ||
// Adapters will automatically handle the difference of precision | ||
wad = amt.mul(10**(18 - IJoin(gemJoin).dec())); | ||
} | ||
|
||
function toInt256(uint256 x) internal pure returns (int256 y) { | ||
y = int256(x); | ||
require(y >= 0, "int256-overflow"); | ||
} | ||
} | ||
|
||
//TODO:This eventually should be library not inheritance, it can be used as "using MakerTools for IVat" | ||
contract MakerCalculations is MakerMath { | ||
uint256 constant RAY = 10**27; | ||
using SafeMath for uint256; | ||
|
||
function _getWipeDart( | ||
address vat, | ||
uint256 dai, | ||
address urn, | ||
bytes32 ilk | ||
) internal view returns (int256 dart) { | ||
// Gets actual rate from the vat | ||
(, uint256 rate, , , ) = IVat(vat).ilks(ilk); | ||
// Gets actual art value of the urn | ||
(, uint256 art) = IVat(vat).urns(ilk, urn); | ||
|
||
// Uses the whole dai balance in the vat to reduce the debt | ||
dart = toInt256(dai / rate); | ||
// Checks the calculated dart is not higher than urn.art (total debt), otherwise uses its value | ||
dart = uint256(dart) <= art ? -dart : -toInt256(art); | ||
} | ||
|
||
function _getWipeAllWad( | ||
address vat, | ||
address usr, | ||
address urn, | ||
bytes32 ilk | ||
) internal view returns (uint256 wad) { | ||
// Gets actual rate from the vat | ||
(, uint256 rate, , , ) = IVat(vat).ilks(ilk); | ||
// Gets actual art value of the urn | ||
(, uint256 art) = IVat(vat).urns(ilk, urn); | ||
// Gets actual dai amount in the urn | ||
uint256 dai = IVat(vat).dai(usr); | ||
|
||
uint256 rad = art.mul(rate).sub(dai); | ||
wad = rad / RAY; | ||
|
||
// If the rad precision has some dust, it will need to request for 1 extra wad wei | ||
wad = wad.mul(RAY) < rad ? wad + 1 : wad; | ||
} | ||
} |
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,44 @@ | ||
pragma solidity ^0.8.1; | ||
import "./MakerCalculations.sol"; | ||
import "./interfaces/ExternalInterfaces.sol"; | ||
import "./../utils/SafeMath.sol"; | ||
import "./../interfaces/IERC20.sol"; | ||
import "./../interfaces/mcd/IVat.sol"; | ||
import "./../interfaces/mcd/IManager.sol"; | ||
import "./../interfaces/mcd/IDaiJoin.sol"; | ||
import "./../interfaces/mcd/IJoin.sol"; | ||
import "./../../contracts/interfaces/exchange/IExchange.sol"; | ||
|
||
//TODO:This eventually should be library not inheritance | ||
contract MakerTools is MakerCalculations { | ||
address public immutable daijoin; | ||
IERC20 public immutable DAI; | ||
using SafeMath for uint256; | ||
|
||
constructor(address _daiJoin, address _dai) { | ||
daijoin = _daiJoin; | ||
DAI = IERC20(_dai); | ||
} | ||
|
||
function wipeAndFreeGem( | ||
address manager, | ||
address gemJoin, | ||
uint256 cdp, | ||
uint256 borrowedDai, | ||
uint256 collateralDraw | ||
) internal { | ||
address vat = IManager(manager).vat(); | ||
address urn = IManager(manager).urns(cdp); | ||
bytes32 ilk = IManager(manager).ilks(cdp); | ||
|
||
IERC20(DAI).approve(daijoin, borrowedDai); | ||
IDaiJoin(daijoin).join(urn, borrowedDai); | ||
|
||
uint256 wadC = convertTo18(gemJoin, collateralDraw); | ||
|
||
IManager(manager).frob(cdp, -toInt256(wadC), _getWipeDart(vat, IVat(vat).dai(urn), urn, ilk)); | ||
|
||
IManager(manager).flux(cdp, address(this), wadC); | ||
IJoin(gemJoin).exit(address(this), collateralDraw); | ||
} | ||
} |
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.
are we sticking with this struct? it has an abundance of unnecessary fields. could we maybe break it out into
CloseCDPData
,OpenCDPData
etc