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

Audit Snapshot Diff #192

Open
wants to merge 5 commits into
base: audit/lg1-snapshot
Choose a base branch
from
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
9 changes: 6 additions & 3 deletions packages/contracts/contracts/CollateralManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradea
import "./interfaces/ICollateralManager.sol";
import { Collateral, CollateralType, ICollateralEscrowV1 } from "./interfaces/escrow/ICollateralEscrowV1.sol";
import "./interfaces/ITellerV2.sol";

import "./interfaces/IProtocolPausingManager.sol";
import "./interfaces/IHasProtocolPausingManager.sol";
contract CollateralManager is OwnableUpgradeable, ICollateralManager {
/* Storage */
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;
Expand Down Expand Up @@ -78,8 +79,10 @@ contract CollateralManager is OwnableUpgradeable, ICollateralManager {
_;
}

modifier whenProtocolNotPaused() {
require( PausableUpgradeable(address(tellerV2)).paused() == false , "Protocol is paused");
modifier whenProtocolNotPaused() {
address pausingManager = IHasProtocolPausingManager( address(tellerV2) ).getProtocolPausingManager();

require( IProtocolPausingManager(address(pausingManager)).protocolPaused() == false , "Protocol is paused");
_;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ import "./extensions/ExtensionsContextUpgradeable.sol";

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";



/*

Only do decimal expansion if it is an ERC20 not anything else !!

*/

contract LenderCommitmentForwarder_U1 is
ExtensionsContextUpgradeable, //this should always be first for upgradeability
TellerV2MarketForwarder_G2,
Expand Down Expand Up @@ -186,17 +194,23 @@ contract LenderCommitmentForwarder_U1 is
uint16 _poolOracleLtvRatio //generally always between 0 and 100 % , 0 to 10000
) public returns (uint256 commitmentId_) {
commitmentId_ = commitmentCount++;

require(
_commitment.lender == _msgSender(),
"unauthorized commitment creator"
);

commitments[commitmentId_] = _commitment;

require(_poolRoutes.length == 0 || _commitment.collateralTokenType == CommitmentCollateralType.ERC20 , "can only use pool routes with ERC20 collateral");


//routes length of 0 means ignore price oracle limits
require(_poolRoutes.length <= 2, "invalid pool routes length");




for (uint256 i = 0; i < _poolRoutes.length; i++) {
commitmentUniswapPoolRoutes[commitmentId_].push(_poolRoutes[i]);
}
Expand Down Expand Up @@ -648,13 +662,26 @@ contract LenderCommitmentForwarder_U1 is
return 0;
}

return
if (_collateralTokenType == CommitmentCollateralType.ERC20) {
return
MathUpgradeable.mulDiv(
_principalAmount,
STANDARD_EXPANSION_FACTOR,
_maxPrincipalPerCollateralAmount,
MathUpgradeable.Rounding.Up
);
}

//for NFTs, do not use the uniswap expansion factor
return
MathUpgradeable.mulDiv(
_principalAmount,
1,
_maxPrincipalPerCollateralAmount,
MathUpgradeable.Rounding.Up
);


}

/**
Expand Down Expand Up @@ -787,8 +814,8 @@ contract LenderCommitmentForwarder_U1 is
(sqrtPriceX96, , , , , , ) = IUniswapV3Pool(uniswapV3Pool).slot0();
} else {
uint32[] memory secondsAgos = new uint32[](2);
secondsAgos[0] = twapInterval; // from (before)
secondsAgos[1] = 0; // to (now)
secondsAgos[0] = twapInterval + 1; // from (before)
secondsAgos[1] = 1; // one block prior

(int56[] memory tickCumulatives, ) = IUniswapV3Pool(uniswapV3Pool)
.observe(secondsAgos);
Expand Down Expand Up @@ -888,6 +915,24 @@ contract LenderCommitmentForwarder_U1 is
return commitments[_commitmentId].maxPrincipal;
}

function getCommitmentPrincipalTokenAddress(uint256 _commitmentId)
external
view
returns (address)
{
return commitments[_commitmentId].principalTokenAddress;
}

function getCommitmentCollateralTokenAddress(uint256 _commitmentId)
external
view
returns (address)
{
return commitments[_commitmentId].collateralTokenAddress;
}



//Overrides
function _msgSender()
internal
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
// 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";




contract LoanReferralForwarder
{
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 CommitmentAcceptedWithReferral(
uint256 indexed bidId,
address indexed recipient,
uint256 fundsRemaining,
uint256 reward,
address rewardRecipient
);

/**
*
* @notice Initializes the FlashRolloverLoan with necessary contract addresses.
*
* @dev Using a custom OpenZeppelin upgrades tag. Ensure the constructor logic is safe for upgrades.
*
* @param _tellerV2 The address of the TellerV2 contract.

*/
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(
address _tellerV2

) {
TELLER_V2 = ITellerV2(_tellerV2);

}



/*

*/
function acceptCommitmentWithReferral(
address _commitmentForwarder, //leave 0 if using smart commitment address


AcceptCommitmentArgs calldata _acceptCommitmentArgs ,


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;

// require( fundsRemaining >= _minAmountReceived, "Insufficient funds received" );


IERC20Upgradeable(principalTokenAddress).transfer(
_rewardRecipient,
_reward
);

IERC20Upgradeable(principalTokenAddress).transfer(
_recipient,
fundsRemaining - _reward
);


emit CommitmentAcceptedWithReferral(bidId_, _recipient, fundsRemaining, _reward, _rewardRecipient);


}


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();
}
}
Loading
Loading