Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions contracts/interfaces/mcd/IChainLog.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity ^0.8.1;

abstract contract IChainLog {
function getAddress(bytes32 _key) public view virtual returns (address addr);
}
27 changes: 27 additions & 0 deletions contracts/interfaces/misc/IChainLogView.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.1;

abstract contract IChainLogView {
/**
* @notice Gets the address of a service by its name
* @param serviceName The name of the service
* @return The address of the service
*/

function getServiceAddress(string calldata serviceName) external view virtual returns (address);

/**
* @notice Gets the address of a join adapter by its ilk name
* @param ilkName The name of the ilk
* @return The address of the join adapter
*/
function getIlkJoinAddressByName(string calldata ilkName) external view virtual returns (address);

/**
* @notice Gets the address of a join adapter by its ilk hash
* @param ilkHash The hash of the ilk name
* @return The address of the join adapter
*/
function getIlkJoinAddressByHash(bytes32 ilkHash) public view virtual returns (address);
}
6 changes: 6 additions & 0 deletions contracts/interfaces/misc/IProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.0;

interface IProxy {
function owner() external view returns (address);
}
76 changes: 57 additions & 19 deletions contracts/multiply/MultiplyProxyActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ import "../interfaces/mcd/IVat.sol";
import "../interfaces/mcd/IJug.sol";
import "../interfaces/mcd/IDaiJoin.sol";
import "../interfaces/exchange/IExchange.sol";
import "../interfaces/misc/IProxy.sol";
import "../interfaces/misc/IChainLogView.sol";
import "./ExchangeData.sol";

import "../flash-mint/interface/IERC3156FlashBorrower.sol";
import "../flash-mint/interface/IERC3156FlashLender.sol";
import {console} from "hardhat/console.sol";

pragma solidity ^0.8.1;
pragma abicoder v2;
Expand Down Expand Up @@ -69,15 +72,26 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
address public immutable WETH;
address public immutable DAI;
address public immutable DAIJOIN;
address public immutable CDP_MANAGER;
address public immutable JUG;
address public immutable EXCHANGE;
address public immutable SELF;
address public immutable MakerChangeLog ;

constructor(
address _weth,
address _dai,
address _daiJoin
address _daiJoin,
address _makerChangeLog
) {
WETH = _weth;
DAI = _dai;
DAIJOIN = _daiJoin;
MakerChangeLog = _makerChangeLog;
SELF = address(this);
JUG = 0x19c0976f590D67707E62397C87829d896Dc0f1F1;
CDP_MANAGER = 0x5ef30b9986345249bc32d8928B7ee64DE9435E39;
EXCHANGE = 0xb5eB8cB6cED6b6f8E13bcD502fb489Db4a726C7B;
}

modifier logMethodName(
Expand All @@ -92,6 +106,20 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
data.methodName = "";
}

function validateAndCorrectInputData(CdpData memory cdpData, AddressRegistry memory addressRegistry) public view{
require(addressRegistry.jug == JUG, "mpa-jug-invalid");
require(addressRegistry.manager == CDP_MANAGER, "mpa-manager-invalid");
require(addressRegistry.multiplyProxyActions == SELF, "mpa-self-invalid");
require(addressRegistry.lender == IChainLogView(MakerChangeLog).getServiceAddress("MCD_FLASH"), "mpa-FL-invalid");
require(addressRegistry.exchange == EXCHANGE, "mpa-exchange-invalid");
address cdpOwner = IProxy(IManager(CDP_MANAGER).owns(cdpData.cdpId)).owner();
//address cdpOwner = IProxy(IManager(addressRegistry.manager).owns(cdpData.cdpId)).owner();
bytes32 ilk = IJoin(cdpData.gemJoin).ilk();
cdpData.ilk = ilk;
require(cdpData.fundsReceiver == cdpOwner, "mpa-fundsReceiver-not-owner");
require(cdpData.gemJoin == IChainLogView(MakerChangeLog).getIlkJoinAddressByHash(cdpData.ilk), "mpa-wrong-gemJoin");
}

function takeAFlashLoan(
AddressRegistry memory addressRegistry,
CdpData memory cdpData,
Expand All @@ -102,7 +130,6 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
addressRegistry.multiplyProxyActions,
1
);

IERC3156FlashLender(addressRegistry.lender).flashLoan(
IERC3156FlashBorrower(addressRegistry.multiplyProxyActions),
DAI,
Expand Down Expand Up @@ -153,21 +180,23 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
function openMultiplyVault(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
)
public
payable
logMethodName("openMultiplyVault", cdpData, addressRegistry.multiplyProxyActions)
{

cdpData.ilk = IJoin(cdpData.gemJoin).ilk();
cdpData.cdpId = IManager(addressRegistry.manager).open(cdpData.ilk, address(this));
validateAndCorrectInputData(cdpData, addressRegistry);
increaseMultipleDepositCollateral(exchangeData, cdpData, addressRegistry);
}

function increaseMultipleDepositCollateral(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
)
public
payable
Expand All @@ -177,6 +206,7 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
addressRegistry.multiplyProxyActions
)
{
validateAndCorrectInputData(cdpData, addressRegistry);
IGem gem = IJoin(cdpData.gemJoin).gem();

if (address(gem) == WETH) {
Expand Down Expand Up @@ -204,7 +234,7 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {

function drawDaiDebt(
CdpData memory cdpData,
AddressRegistry calldata addressRegistry,
AddressRegistry memory addressRegistry,
uint256 amount
) internal {
address urn = IManager(addressRegistry.manager).urns(cdpData.cdpId);
Expand All @@ -225,11 +255,12 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
function increaseMultipleDepositDai(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
)
public
logMethodName("increaseMultipleDepositDai", cdpData, addressRegistry.multiplyProxyActions)
{
validateAndCorrectInputData(cdpData, addressRegistry);
if (cdpData.skipFL) {
IERC20(DAI).transferFrom(msg.sender, address(this), cdpData.depositDai);
} else {
Expand All @@ -245,15 +276,16 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
function increaseMultiple(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
) public logMethodName("increaseMultiple", cdpData, addressRegistry.multiplyProxyActions) {
validateAndCorrectInputData(cdpData, addressRegistry);
increaseMultipleInternal(exchangeData, cdpData, addressRegistry);
}

function increaseMultipleInternal(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
) internal {
cdpData.ilk = IJoin(cdpData.gemJoin).ilk();

Expand All @@ -280,15 +312,16 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
function decreaseMultiple(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
) public logMethodName("decreaseMultiple", cdpData, addressRegistry.multiplyProxyActions) {
validateAndCorrectInputData(cdpData, addressRegistry);
decreaseMultipleInternal(exchangeData, cdpData, addressRegistry);
}

function decreaseMultipleInternal(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
) internal {
cdpData.ilk = IJoin(cdpData.gemJoin).ilk();

Expand All @@ -304,33 +337,34 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
function decreaseMultipleWithdrawCollateral(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
)
public
logMethodName(
"decreaseMultipleWithdrawCollateral",
cdpData,
addressRegistry.multiplyProxyActions
)
addressRegistry.multiplyProxyActions)
{
validateAndCorrectInputData(cdpData, addressRegistry);
decreaseMultipleInternal(exchangeData, cdpData, addressRegistry);
}

function decreaseMultipleWithdrawDai(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
)
public
logMethodName("decreaseMultipleWithdrawDai", cdpData, addressRegistry.multiplyProxyActions)
{
validateAndCorrectInputData(cdpData, addressRegistry);
decreaseMultipleInternal(exchangeData, cdpData, addressRegistry);
}

function closeVaultExitGeneric(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry,
AddressRegistry memory addressRegistry,
uint8 mode
) private {
cdpData.ilk = IJoin(cdpData.gemJoin).ilk();
Expand Down Expand Up @@ -362,7 +396,7 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
function closeVaultExitCollateral(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
)
public
logMethodName("closeVaultExitCollateral", cdpData, addressRegistry.multiplyProxyActions)
Expand All @@ -373,8 +407,9 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
function closeVaultExitDai(
ExchangeData calldata exchangeData,
CdpData memory cdpData,
AddressRegistry calldata addressRegistry
AddressRegistry memory addressRegistry
) public logMethodName("closeVaultExitDai", cdpData, addressRegistry.multiplyProxyActions) {
validateAndCorrectInputData(cdpData, addressRegistry);
require(cdpData.skipFL == false, "cannot close to DAI if FL not used");
closeVaultExitGeneric(exchangeData, cdpData, addressRegistry, 3);
}
Expand Down Expand Up @@ -504,13 +539,17 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
IERC20(DAI).approve(address(exchange), exchangeData.fromTokenAmount.add(cdpData.depositDai)),
"MPA / Could not approve Exchange for DAI"
);
console.log("exchange", address(exchange));
console.log("before swap");
console.logBytes(exchangeData._exchangeCalldata);
exchange.swapDaiForToken(
exchangeData.toTokenAddress,
exchangeData.fromTokenAmount.add(cdpData.depositDai),
exchangeData.minToTokenAmount,
exchangeData.exchangeAddress,
exchangeData._exchangeCalldata
);
console.log("after swap");
//here we add collateral we got from exchange, if skipFL then borrowedDai = 0
joinDrawDebt(cdpData, borrowedDai, addressRegistry.manager, addressRegistry.jug);
//if some DAI are left after exchange return them to the user
Expand Down Expand Up @@ -661,6 +700,7 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
uint256 borrowedDaiAmount,
uint256 ink
) private {
// TODO:
IExchange exchange = IExchange(addressRegistry.exchange);
address gemAddress = address(IJoin(cdpData.gemJoin).gem());

Expand Down Expand Up @@ -769,7 +809,6 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
CdpData memory cdpData,
AddressRegistry memory addressRegistry
) = abi.decode(params, (uint8, ExchangeData, CdpData, AddressRegistry));

require(msg.sender == address(addressRegistry.lender), "mpa-untrusted-lender");

uint256 borrowedDaiAmount = amount.add(fee);
Expand Down Expand Up @@ -804,7 +843,6 @@ contract MultiplyProxyActions is IERC3156FlashBorrower {
cdpData.borrowCollateral
);
}

IERC20(token).approve(addressRegistry.lender, borrowedDaiAmount);

return keccak256("ERC3156FlashBorrower.onFlashLoan");
Expand Down
63 changes: 63 additions & 0 deletions contracts/views/ChainLogView.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.1;

import { IChainLog } from "../interfaces/mcd/IChainLog.sol";

/**
* @title ChainLogView
* @notice Reads the Chainlog contract to get the address of a service by its name
*/
contract ChainLogView {
address public immutable chainlogAddress;

constructor(address _chainlogAddress) {
chainlogAddress = _chainlogAddress;
}

function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) {
uint8 i = 0;
while (i < 32 && _bytes32[i] != 0) {
i++;
}
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
if (_bytes32[i] == bytes1("-")) {
bytesArray[i] = bytes1("_");
} else {
bytesArray[i] = _bytes32[i];
}
}
return string(bytesArray);
}

/**
* @notice Gets the address of a service by its name
* @param serviceName The name of the service
* @return The address of the service
*/

function getServiceAddress(string calldata serviceName) public view returns (address) {
bytes32 serviceHash = bytes32(abi.encodePacked(serviceName));
return IChainLog(chainlogAddress).getAddress(serviceHash);
}

/**
* @notice Gets the address of a join adapter by its ilk name
* @param ilkName The name of the ilk
* @return The address of the join adapter
*/
function getIlkJoinAddressByName(string calldata ilkName) public view returns (address) {
bytes32 ilkHash = bytes32(abi.encodePacked("MCD_JOIN_", ilkName));
return IChainLog(chainlogAddress).getAddress(ilkHash);
}

/**
* @notice Gets the address of a join adapter by its ilk hash
* @param ilkHash The hash of the ilk name
* @return The address of the join adapter
*/
function getIlkJoinAddressByHash(bytes32 ilkHash) public view returns (address) {
bytes32 newIlkHash = bytes32(abi.encodePacked("MCD_JOIN_", bytes32ToString(ilkHash)));
return IChainLog(chainlogAddress).getAddress(newIlkHash);
}
}
2 changes: 1 addition & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const config = {
),
},
solidity: {
version: '0.8.1',
version: '0.8.14',
settings: {
optimizer: {
enabled: true,
Expand Down
2 changes: 2 additions & 0 deletions test/common/cosntants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ export const ADDRESSES = {
dai: '0x6b175474e89094c44da98b954eedeac495271d0f',
weth: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
daijoin: '0x9759A6Ac90977b93B58547b4A71c78317f391A28',
chainlog: '0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F',
exchange: '0xb5eB8cB6cED6b6f8E13bcD502fb489Db4a726C7B',
}
Loading