Skip to content
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

Flashswap Rollover Contract #199

Merged
merged 23 commits into from
Jan 30, 2025
Merged
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
60 changes: 60 additions & 0 deletions packages/contracts/.openzeppelin/polygon.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,26 @@
"address": "0x2fF5ea5CF5061EB0fcfB7A2AafB8CCC79f3F73ea",
"txHash": "0x9fa729ed52022a919928bba61f0b016e4d2ea6f44f267a4a13fe1445838b5ae3",
"kind": "transparent"
},
{
"address": "0xA6406fcbCCe89B899344d3E0D004DfeAa225a259",
"txHash": "0x0487a9a056085572743315eda8f7521366af80910d7741709934c2088b48c0ec",
"kind": "transparent"
},
{
"address": "0x61F3673CAD0B99Ec18E6Dc242eE67f0ea48CD227",
"txHash": "0xeed24b08837f0526be09f3afe11e0ba98a5db955e7ef6415076653d3e7c4757a",
"kind": "transparent"
},
{
"address": "0x905BF03956416fC02494A55d44f6A84E5703311a",
"txHash": "0xe8d969fe884f614982b596da4c09b0e602fcf03943c293198ad28deaa38ed3d4",
"kind": "transparent"
},
{
"address": "0x9d337576FB254DcDBea229b5105611004D41FeB2",
"txHash": "0xd6469c0891057adde864e4fbd419efa3e01757dcd3cb742f050848f44c3a9451",
"kind": "transparent"
}
],
"impls": {
Expand Down Expand Up @@ -19991,6 +20011,46 @@
},
"namespaces": {}
}
},
"b9d0fe753953c0f3af7b182ffd8dd7849b5f917b6d69101ba673c11fb4c3d89e": {
"address": "0xB2A57902bd1E1A0a6Cf673a6B653C303E9713411",
"txHash": "0xbc99270c2c4a09812d277306fbea149efbda0ebe641887fb52ed5a9c26421455",
"layout": {
"solcVersion": "0.8.11",
"storage": [],
"types": {},
"namespaces": {}
}
},
"47bb7b441f57437f18168f193d8e5abe4f6150371737a149808251bbb3bae92d": {
"address": "0x22CA04516a4399C19f1296E0CE9691E87107cF57",
"txHash": "0xac52cdb229ceac334c587016c33471c8ad23f488acd365e280dc8b17c5aeebb8",
"layout": {
"solcVersion": "0.8.11",
"storage": [],
"types": {},
"namespaces": {}
}
},
"fcdecb4bcb2c746b9feb7823b85d79c3457e4e2358d535a60e505a20777dde6d": {
"address": "0x4A4aeDb075669cFB18E46e41231d121183DED42C",
"txHash": "0x1621738ca047d633e4adfdfb7ef6219491da7a51509e7ec9526be5f4ca0f7f22",
"layout": {
"solcVersion": "0.8.11",
"storage": [],
"types": {},
"namespaces": {}
}
},
"1311ac40801c2ead8adf02d3a3e9626f21f404fe5233e08e18f639433414e5b8": {
"address": "0x5f53f8ae7AbA383E3155B026721E10007CDfaCdB",
"txHash": "0xd61314c0eaaf8fad091008e2cd7671b1a0228d9d19e49d2b2c053c6794a3d737",
"layout": {
"solcVersion": "0.8.11",
"storage": [],
"types": {},
"namespaces": {}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Contracts
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

// Interfaces
import "../interfaces/ITellerV2.sol";
import "../interfaces/IProtocolFee.sol";
import "../interfaces/ITellerV2Storage.sol";
import "../interfaces/IMarketRegistry.sol";
import "../interfaces/ISmartCommitment.sol";
import "../interfaces/ISmartCommitmentForwarder.sol";
import "../interfaces/IFlashRolloverLoan_G4.sol";
import "../libraries/NumbersLib.sol";

import { ILenderCommitmentForwarder } from "../interfaces/ILenderCommitmentForwarder.sol";

import { ILenderCommitmentForwarder_U1 } from "../interfaces/ILenderCommitmentForwarder_U1.sol";

import '../libraries/uniswap/periphery/libraries/TransferHelper.sol';


contract LoanReferralForwarderV2
{
using AddressUpgradeable for address;
using NumbersLib for uint256;

/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
ITellerV2 public immutable TELLER_V2;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable



struct AcceptCommitmentArgs {
uint256 commitmentId;
address smartCommitmentAddress; //if this is not address(0), we will use this ! leave empty if not used.
uint256 principalAmount;
uint256 collateralAmount;
uint256 collateralTokenId;
address collateralTokenAddress;
uint16 interestRate;
uint32 loanDuration;
bytes32[] merkleProof; //empty array if not used
}


event CommitmentAcceptedWithReward(
uint256 indexed bidId,
address indexed recipient,
address principalTokenAddress,
uint256 fundsRemaining,
uint256 reward,
address rewardRecipient,
uint256 atmId
);


constructor(
address _tellerV2

) {
TELLER_V2 = ITellerV2(_tellerV2);

}



/*

*/
function acceptCommitmentWithReferral(
address _commitmentForwarder,

AcceptCommitmentArgs calldata _acceptCommitmentArgs ,

uint256 _atmId,
address _recipient,
uint256 _reward,
address _rewardRecipient

) external returns (uint256 bidId_) {


address principalTokenAddress = address(0);
uint256 balanceBefore;


require(_reward <= _acceptCommitmentArgs.principalAmount / 10, "Reward can be no more than 10% of principal");

if (_acceptCommitmentArgs.smartCommitmentAddress != address(0)) {


principalTokenAddress = ISmartCommitment(_acceptCommitmentArgs.smartCommitmentAddress).getPrincipalTokenAddress ();

// Accept commitment and receive funds to this contract
balanceBefore = IERC20(principalTokenAddress).balanceOf(address(this));

bidId_ = _acceptSmartCommitmentWithRecipient(
_commitmentForwarder,
_acceptCommitmentArgs

);


}else{
principalTokenAddress = ILenderCommitmentForwarder_U1(_commitmentForwarder)
.getCommitmentPrincipalTokenAddress (_acceptCommitmentArgs.commitmentId);

// Accept commitment and receive funds to this contract
balanceBefore = IERC20(principalTokenAddress).balanceOf(address(this));


bidId_ = _acceptCommitmentWithRecipient(
_commitmentForwarder,
_acceptCommitmentArgs

);



}

uint256 balanceAfter = IERC20(principalTokenAddress).balanceOf(address(this));

uint256 fundsRemaining = balanceAfter - balanceBefore;


if (_reward > 0) {

TransferHelper.safeTransferFrom(principalTokenAddress, address(this), _rewardRecipient, _reward);


}

TransferHelper.safeTransferFrom(principalTokenAddress, address(this), _recipient, fundsRemaining - _reward);


emit CommitmentAcceptedWithReward( bidId_, _recipient, principalTokenAddress, fundsRemaining, _reward, _rewardRecipient , _atmId);


}


function _acceptSmartCommitmentWithRecipient(
address _smartCommitmentForwarder,
AcceptCommitmentArgs calldata _acceptCommitmentArgs


) internal returns (uint256 bidId_) {

bytes memory responseData = address(_smartCommitmentForwarder)
.functionCall(
abi.encodePacked(
abi.encodeWithSelector(
ISmartCommitmentForwarder
.acceptSmartCommitmentWithRecipient
.selector,
_acceptCommitmentArgs.smartCommitmentAddress,
_acceptCommitmentArgs.principalAmount,
_acceptCommitmentArgs.collateralAmount,
_acceptCommitmentArgs.collateralTokenId,
_acceptCommitmentArgs.collateralTokenAddress,
address(this),
_acceptCommitmentArgs.interestRate,
_acceptCommitmentArgs.loanDuration
),
msg.sender // borrower
)
);


(bidId_) = abi.decode(responseData, (uint256));



}



function _acceptCommitmentWithRecipient(
address _commitmentForwarder,
AcceptCommitmentArgs calldata _acceptCommitmentArgs


) internal returns (uint256 bidId_) {

bytes memory responseData = address(_commitmentForwarder)
.functionCall(
abi.encodePacked(
abi.encodeWithSelector(
ILenderCommitmentForwarder
.acceptCommitmentWithRecipient
.selector,
_acceptCommitmentArgs.commitmentId,
_acceptCommitmentArgs.principalAmount,
_acceptCommitmentArgs.collateralAmount,
_acceptCommitmentArgs.collateralTokenId,
_acceptCommitmentArgs.collateralTokenAddress,
address(this),
_acceptCommitmentArgs.interestRate,
_acceptCommitmentArgs.loanDuration
),
msg.sender //borrower
)
);

(bidId_) = abi.decode(responseData, (uint256));


}


/**
* @notice Fetches the protocol fee percentage from the Teller V2 protocol.
* @return The protocol fee percentage as defined in the Teller V2 protocol.
*/
function _getProtocolFeePct() internal view returns (uint16) {
return IProtocolFee(address(TELLER_V2)).protocolFee();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";

// Interfaces
import "../../interfaces/ITellerV2.sol";
import "../../interfaces/IProtocolFee.sol";
import "../../interfaces/ITellerV2Storage.sol";
import "../../interfaces/IMarketRegistry.sol";
import "../../interfaces/ILenderCommitmentForwarder.sol";
import "../../interfaces/ICommitmentRolloverLoan.sol";
import "../../libraries/NumbersLib.sol";
import "../../../interfaces/ITellerV2.sol";
import "../../../interfaces/IProtocolFee.sol";
import "../../../interfaces/ITellerV2Storage.sol";
import "../../../interfaces/IMarketRegistry.sol";
import "../../../interfaces/ILenderCommitmentForwarder.sol";
import "../../../interfaces/ICommitmentRolloverLoan.sol";
import "../../../libraries/NumbersLib.sol";

contract CommitmentRolloverLoan is ICommitmentRolloverLoan {
using AddressUpgradeable for address;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

// Interfaces
import "../../interfaces/ITellerV2.sol";
import "../../interfaces/IProtocolFee.sol";
import "../../interfaces/ITellerV2Storage.sol";
import "../../interfaces/IMarketRegistry.sol";
import "../../interfaces/ILenderCommitmentForwarder.sol";
import "../../interfaces/IFlashRolloverLoan.sol";
import "../../libraries/NumbersLib.sol";

import { IPool } from "../../interfaces/aave/IPool.sol";
import { IFlashLoanSimpleReceiver } from "../../interfaces/aave/IFlashLoanSimpleReceiver.sol";
import { IPoolAddressesProvider } from "../../interfaces/aave/IPoolAddressesProvider.sol";
import "../../../interfaces/ITellerV2.sol";
import "../../../interfaces/IProtocolFee.sol";
import "../../../interfaces/ITellerV2Storage.sol";
import "../../../interfaces/IMarketRegistry.sol";
import "../../../interfaces/ILenderCommitmentForwarder.sol";
import "../../../interfaces/IFlashRolloverLoan.sol";
import "../../../libraries/NumbersLib.sol";

import { IPool } from "../../../interfaces/aave/IPool.sol";
import { IFlashLoanSimpleReceiver } from "../../../interfaces/aave/IFlashLoanSimpleReceiver.sol";
import { IPoolAddressesProvider } from "../../../interfaces/aave/IPoolAddressesProvider.sol";

//https://docs.aave.com/developers/v/1.0/tutorials/performing-a-flash-loan/...-in-your-project

Expand Down
Loading