Skip to content

Commit

Permalink
Fix OsTokenFlashLoans, tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tsudmi committed Sep 10, 2024
1 parent a9d0504 commit 3765d9d
Show file tree
Hide file tree
Showing 29 changed files with 274 additions and 113 deletions.
7 changes: 1 addition & 6 deletions abi/IOsTokenFlashLoans.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"name": "caller",
"type": "address"
},
{
Expand All @@ -20,11 +20,6 @@
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "osTokenShares",
Expand Down
12 changes: 6 additions & 6 deletions abi/IOsTokenVaultEscrow.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"internalType": "uint64",
"name": "liqThresholdPercent",
"type": "uint256"
"type": "uint64"
},
{
"indexed": false,
Expand Down Expand Up @@ -316,9 +316,9 @@
"name": "liqThresholdPercent",
"outputs": [
{
"internalType": "uint256",
"internalType": "uint64",
"name": "",
"type": "uint256"
"type": "uint64"
}
],
"stateMutability": "view",
Expand Down Expand Up @@ -471,9 +471,9 @@
{
"inputs": [
{
"internalType": "uint256",
"internalType": "uint64",
"name": "_liqThresholdPercent",
"type": "uint256"
"type": "uint64"
},
{
"internalType": "uint256",
Expand Down
9 changes: 4 additions & 5 deletions contracts/interfaces/IOsTokenFlashLoans.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ pragma solidity ^0.8.22;
*/
interface IOsTokenFlashLoans {
/**
* @notice Event emitted on position creation
* @param recipient The address of the recipient
* @notice Event emitted on flash loan
* @param caller The address of the caller
* @param amount The flashLoan osToken shares amount
*/
event OsTokenFlashLoan(address indexed recipient, uint256 amount);
event OsTokenFlashLoan(address indexed caller, uint256 amount);

/**
* @notice Flash loan OsToken shares
* @param recipient The address of the recipient
* @param osTokenShares The flashLoan osToken shares amount
* @param userData Arbitrary data passed to the `IOsTokenFlashLoanRecipient.receiveFlashLoan` function
*/
function flashLoan(address recipient, uint256 osTokenShares, bytes memory userData) external;
function flashLoan(uint256 osTokenShares, bytes memory userData) external;
}
6 changes: 3 additions & 3 deletions contracts/interfaces/IOsTokenVaultEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ interface IOsTokenVaultEscrow is IMulticall {
* @param liqThresholdPercent The liquidation threshold percent
* @param liqBonusPercent The liquidation bonus percent
*/
event LiqConfigUpdated(uint256 liqThresholdPercent, uint256 liqBonusPercent);
event LiqConfigUpdated(uint64 liqThresholdPercent, uint256 liqBonusPercent);

/**
* @notice Event emitted on authenticator update
Expand All @@ -123,7 +123,7 @@ interface IOsTokenVaultEscrow is IMulticall {
* @notice The liquidation threshold percent
* @return The liquidation threshold percent starting from which the osToken shares can be liquidated
*/
function liqThresholdPercent() external view returns (uint256);
function liqThresholdPercent() external view returns (uint64);

/**
* @notice The liquidation bonus percent
Expand Down Expand Up @@ -230,5 +230,5 @@ interface IOsTokenVaultEscrow is IMulticall {
* @param _liqThresholdPercent The liquidation threshold percent
* @param _liqBonusPercent The liquidation bonus percent
*/
function updateLiqConfig(uint256 _liqThresholdPercent, uint256 _liqBonusPercent) external;
function updateLiqConfig(uint64 _liqThresholdPercent, uint256 _liqBonusPercent) external;
}
58 changes: 58 additions & 0 deletions contracts/mocks/OsTokenFlashLoanRecipientMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.22;

import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {IOsTokenFlashLoanRecipient} from '../interfaces/IOsTokenFlashLoanRecipient.sol';
import {IOsTokenFlashLoans} from '../interfaces/IOsTokenFlashLoans.sol';
import {Errors} from '../libraries/Errors.sol';

/**
* @title OsTokenFlashLoanRecipientMock
* @notice Mock contract that acts both as the caller and receiver of the flash loan
*/
contract OsTokenFlashLoanRecipientMock is IOsTokenFlashLoanRecipient {
address public osToken;
bool public shouldRepayLoan; // Simulate success or failure in repaying the loan
address public flashLoanContract;

/**
* @dev Constructor to set the osToken address and flash loan contract
* @param _osToken The address of the OsToken contract
* @param _flashLoanContract The address of the OsTokenFlashLoans contract
*/
constructor(address _osToken, address _flashLoanContract) {
osToken = _osToken;
flashLoanContract = _flashLoanContract;
shouldRepayLoan = true; // Default to repaying the loan
}

function receiveFlashLoan(uint256 osTokenShares, bytes calldata) external override {
require(msg.sender == flashLoanContract, 'Caller is not flash loan contract');

// Do something with the userData if needed

// If the recipient is supposed to repay the loan
if (shouldRepayLoan) {
// Repay the loan by transferring back the borrowed osTokenShares
IERC20(osToken).transfer(msg.sender, osTokenShares);
}
// If shouldRepayLoan is false, we simulate a failure by not transferring back the tokens
}

/**
* @notice Executes a flash loan from the OsTokenFlashLoans contract
* @param osTokenShares The amount of OsToken shares to borrow
* @param userData Arbitrary data to pass along with the flash loan
*/
function executeFlashLoan(uint256 osTokenShares, bytes calldata userData) external {
IOsTokenFlashLoans(flashLoanContract).flashLoan(osTokenShares, userData);
}

/**
* @notice Toggle the loan repayment behavior (for testing)
* @param repay Set to true if the loan should be repaid, false otherwise
*/
function setShouldRepayLoan(bool repay) external {
shouldRepayLoan = repay;
}
}
2 changes: 1 addition & 1 deletion contracts/tokens/EthOsTokenVaultEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ contract EthOsTokenVaultEscrow is ReentrancyGuard, OsTokenVaultEscrow {
address osTokenConfig,
address initialOwner,
address _authenticator,
uint256 _liqThresholdPercent,
uint64 _liqThresholdPercent,
uint256 _liqBonusPercent
)
ReentrancyGuard()
Expand Down
2 changes: 1 addition & 1 deletion contracts/tokens/GnoOsTokenVaultEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract GnoOsTokenVaultEscrow is OsTokenVaultEscrow {
address osTokenConfig,
address initialOwner,
address _authenticator,
uint256 _liqThresholdPercent,
uint64 _liqThresholdPercent,
uint256 _liqBonusPercent,
address gnoToken
)
Expand Down
16 changes: 6 additions & 10 deletions contracts/tokens/OsTokenFlashLoans.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {Errors} from '../libraries/Errors.sol';
* @notice Handles OsToken flash loans
*/
contract OsTokenFlashLoans is ReentrancyGuard, IOsTokenFlashLoans {
uint256 private constant _maxFlashLoanAmount = 1_000_000 ether;
uint256 private constant _maxFlashLoanAmount = 100_000 ether;
address private immutable _osToken;

/**
Expand All @@ -27,11 +27,7 @@ contract OsTokenFlashLoans is ReentrancyGuard, IOsTokenFlashLoans {
}

/// @inheritdoc IOsTokenFlashLoans
function flashLoan(
address recipient,
uint256 osTokenShares,
bytes memory userData
) external override nonReentrant {
function flashLoan(uint256 osTokenShares, bytes memory userData) external override nonReentrant {
// check if not more than max flash loan amount requested
if (osTokenShares == 0 || osTokenShares > _maxFlashLoanAmount) {
revert Errors.InvalidShares();
Expand All @@ -40,11 +36,11 @@ contract OsTokenFlashLoans is ReentrancyGuard, IOsTokenFlashLoans {
// get current balance
uint256 preLoanBalance = IERC20(_osToken).balanceOf(address(this));

// mint OsToken shares for the recipient
IOsToken(_osToken).mint(recipient, osTokenShares);
// mint OsToken shares for the caller
IOsToken(_osToken).mint(msg.sender, osTokenShares);

// execute callback
IOsTokenFlashLoanRecipient(recipient).receiveFlashLoan(osTokenShares, userData);
IOsTokenFlashLoanRecipient(msg.sender).receiveFlashLoan(osTokenShares, userData);

// get post loan balance
uint256 postLoanBalance = IERC20(_osToken).balanceOf(address(this));
Expand All @@ -58,6 +54,6 @@ contract OsTokenFlashLoans is ReentrancyGuard, IOsTokenFlashLoans {
IOsToken(address(_osToken)).burn(address(this), osTokenShares);

// emit event
emit OsTokenFlashLoan(recipient, osTokenShares);
emit OsTokenFlashLoan(msg.sender, osTokenShares);
}
}
10 changes: 5 additions & 5 deletions contracts/tokens/OsTokenVaultEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ abstract contract OsTokenVaultEscrow is Ownable2Step, Multicall, IOsTokenVaultEs

mapping(address vault => mapping(uint256 positionTicket => Position)) private _positions;

/// @inheritdoc IOsTokenVaultEscrow
uint256 public override liqThresholdPercent;

/// @inheritdoc IOsTokenVaultEscrow
uint256 public override liqBonusPercent;

/// @inheritdoc IOsTokenVaultEscrow
address public override authenticator;

/// @inheritdoc IOsTokenVaultEscrow
uint64 public override liqThresholdPercent;

/**
* @dev Constructor
* @param osTokenVaultController The address of the OsTokenVaultController contract
Expand All @@ -51,7 +51,7 @@ abstract contract OsTokenVaultEscrow is Ownable2Step, Multicall, IOsTokenVaultEs
address osTokenConfig,
address initialOwner,
address _authenticator,
uint256 _liqThresholdPercent,
uint64 _liqThresholdPercent,
uint256 _liqBonusPercent
) Ownable(msg.sender) {
_osTokenVaultController = IOsTokenVaultController(osTokenVaultController);
Expand Down Expand Up @@ -247,7 +247,7 @@ abstract contract OsTokenVaultEscrow is Ownable2Step, Multicall, IOsTokenVaultEs

/// @inheritdoc IOsTokenVaultEscrow
function updateLiqConfig(
uint256 _liqThresholdPercent,
uint64 _liqThresholdPercent,
uint256 _liqBonusPercent
) public override onlyOwner {
// validate liquidation threshold percent
Expand Down
Loading

0 comments on commit 3765d9d

Please sign in to comment.