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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ contract LenderCommitmentForwarder_G3 is
LenderCommitmentForwarder_G2(_tellerV2, _marketRegistry)
{}

/**
* @notice Returns the TellerV2 address for protocol owner checks.
* @dev Implements the abstract function from ExtensionsContextUpgradeable.
* @dev Uses the immutable _tellerV2 from TellerV2MarketForwarder_G2 parent contract.
*/
function _getTellerV2() internal view override returns (address) {
return _tellerV2;
}

function _msgSender()
internal
view
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ contract LenderCommitmentForwarder_U1 is
UNISWAP_V3_FACTORY = _uniswapV3Factory;
}

/**
* @notice Returns the TellerV2 address for protocol owner checks.
* @dev Implements the abstract function from ExtensionsContextUpgradeable.
* @dev Uses the immutable _tellerV2 from TellerV2MarketForwarder_G2 parent contract.
*/
function _getTellerV2() internal view override returns (address) {
return _tellerV2;
}

/**
* @notice Creates a loan commitment from a lender for a market.
* @param _commitment The new commitment data expressed as a struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,19 @@ contract SmartCommitmentForwarder is
TellerV2MarketForwarder_G3(_protocolAddress, _marketRegistry)
{ }

function initialize() public initializer {
function initialize() public initializer {
__Pausable_init();
__Ownable_init_unchained();
}

/**
* @notice Returns the TellerV2 address for protocol owner checks.
* @dev Implements the abstract function from ExtensionsContextUpgradeable.
* @dev Uses the immutable _tellerV2 from TellerV2MarketForwarder_G2 parent contract.
*/
function _getTellerV2() internal view override returns (address) {
return _tellerV2;
}

function setLiquidationProtocolFeePercent(uint256 _percent)
public onlyProtocolOwner {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,47 @@ import "../../interfaces/IExtensionsContext.sol";
import "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol";

import "@openzeppelin/contracts/access/Ownable.sol";

abstract contract ExtensionsContextUpgradeable is IExtensionsContext {
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;

// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private userExtensions;

mapping(address => bool) private globalExtensions;



event ExtensionAdded(address extension, address sender);
event ExtensionRevoked(address extension, address sender);

event GlobalExtensionAdded(address extension, address sender);
event GlobalExtensionRevoked(address extension, address sender);

/**
* @notice Returns the TellerV2 address used for protocol owner checks.
* @dev Must be implemented by inheriting contracts.
*/
function _getTellerV2() internal view virtual returns (address);

modifier onlyExtensionsProtocolOwner() {
require( Ownable( _getTellerV2() ).owner() == _msgSender() , "Sender not authorized");
_;
}



function hasExtension(address account, address extension)
public
view
returns (bool)
{
return userExtensions[account][extension];
return userExtensions[account][extension] || globalExtensions[extension] ;
}

// -----

function addExtension(address extension) external {
require(
_msgSender() != extension,
Expand All @@ -37,6 +61,22 @@ abstract contract ExtensionsContextUpgradeable is IExtensionsContext {
emit ExtensionRevoked(extension, _msgSender());
}


// ------

function addGlobalExtension(address extension) external onlyExtensionsProtocolOwner {

globalExtensions [extension] = true;
emit GlobalExtensionAdded(extension, _msgSender());
}

function revokeGlobalExtension(address extension) external onlyExtensionsProtocolOwner {
globalExtensions[extension] = false;
emit GlobalExtensionRevoked(extension, _msgSender());
}

// ------

function _msgSender() internal view virtual returns (address sender) {
address sender;

Expand All @@ -58,5 +98,5 @@ abstract contract ExtensionsContextUpgradeable is IExtensionsContext {
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
uint256[48] private __gap;
}
69 changes: 64 additions & 5 deletions packages/contracts/contracts/TellerV2Context.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ pragma solidity >=0.8.0 <0.9.0;

import "./TellerV2Storage.sol";
import "./ERC2771ContextUpgradeable.sol";

import "./interfaces/IOwnable.sol";




/**
* @dev This contract should not use any storage
*
* @dev for OnlyProtocolOwner to work, the wrapping contract must implement owner() [ OZ Ownable ]
*/

abstract contract TellerV2Context is
ERC2771ContextUpgradeable,
ERC2771ContextUpgradeable,
TellerV2Storage
{
using EnumerableSet for EnumerableSet.AddressSet;
Expand All @@ -19,6 +26,14 @@ abstract contract TellerV2Context is
address forwarder,
address sender
);

event ProtocolTrustedForwarderSet(

address forwarder,
address sender,
bool trusted
);

event MarketForwarderApproved(
uint256 indexed marketId,
address indexed forwarder,
Expand All @@ -34,6 +49,22 @@ abstract contract TellerV2Context is
ERC2771ContextUpgradeable(trustedForwarder)
{}



modifier onlyProtocolOwner() {
require( _owner() == _msgSender() , "Sender not authorized");
_;
}


function _owner() internal returns (address) {

return IOwnable( address(this) ) .owner() ;
}




/**
* @notice Checks if an address is a trusted forwarder contract for a given market.
* @param _marketId An ID for a lending market.
Expand All @@ -45,10 +76,19 @@ abstract contract TellerV2Context is
address _trustedMarketForwarder
) public view returns (bool) {
return
_trustedMarketForwarders[_marketId] == _trustedMarketForwarder ||
lenderCommitmentForwarder == _trustedMarketForwarder;
_trustedMarketForwarders[_marketId] == _trustedMarketForwarder ;
}


function isProtocolTrustedForwarder(
address _forwarder
) public view returns (bool) {
return
_protocolTrustedForwarders[_forwarder] == true ;
}



/**
* @notice Checks if an account has approved a forwarder for a market.
* @param _marketId An ID for a lending market.
Expand All @@ -62,10 +102,23 @@ abstract contract TellerV2Context is
address _account
) public view returns (bool) {
return
isTrustedMarketForwarder(_marketId, _forwarder) &&
_approvedForwarderSenders[_forwarder].contains(_account);
( isTrustedMarketForwarder(_marketId, _forwarder) &&
_approvedForwarderSenders[_forwarder].contains(_account) )

|| isProtocolTrustedForwarder( _forwarder )
;
}

function setProtocolTrustedForwarder( address _forwarder, bool _trusted)
external onlyProtocolOwner
{

_protocolTrustedForwarders[_forwarder] = _trusted;
emit ProtocolTrustedForwarderSet( _forwarder, _msgSender(), _trusted);
}



/**
* @notice Sets a trusted forwarder for a lending market.
* @notice The caller must owner the market given. See {MarketRegistry}
Expand Down Expand Up @@ -161,4 +214,10 @@ abstract contract TellerV2Context is
return _msgData();
}
}






}
8 changes: 6 additions & 2 deletions packages/contracts/contracts/TellerV2Storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ abstract contract TellerV2Storage_G1 is TellerV2Storage_G0 {
}

abstract contract TellerV2Storage_G2 is TellerV2Storage_G1 {
address public lenderCommitmentForwarder;
address public lenderCommitmentForwarder; // deprecated
}

abstract contract TellerV2Storage_G3 is TellerV2Storage_G2 {
Expand Down Expand Up @@ -171,4 +171,8 @@ abstract contract TellerV2Storage_G8 is TellerV2Storage_G7 {
address protocolFeeRecipient;
}

abstract contract TellerV2Storage is TellerV2Storage_G8 {}
abstract contract TellerV2Storage_G9 is TellerV2Storage_G8 {
mapping(address => bool) public _protocolTrustedForwarders;}


abstract contract TellerV2Storage is TellerV2Storage_G9 {}
10 changes: 10 additions & 0 deletions packages/contracts/contracts/interfaces/IOwnable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


interface IOwnable {

function owner() external view virtual returns (address) ;


}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
pragma solidity >=0.8.0 <0.9.0;
// SPDX-License-Identifier: MIT


import "forge-std/console.sol";


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


Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
pragma solidity >=0.8.0 <0.9.0;
// SPDX-License-Identifier: MIT


import "forge-std/console.sol";


import {IUniswapPricingLibrary} from "../interfaces/IUniswapPricingLibrary.sol";
Expand Down Expand Up @@ -52,9 +50,7 @@ contract UniswapPricingHelper
);


console.log("ratio");
console.logUint(pool0PriceRatio);
console.logUint(pool1PriceRatio);


return
FullMath.mulDiv(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { DeployFunction } from 'hardhat-deploy/dist/types'

const deployFn: DeployFunction = async (hre) => {
hre.log('----------')
hre.log('')
hre.log('TellerV2: Proposing upgrade...')

const tellerV2 = await hre.contracts.get('TellerV2')
const metaForwarder = await hre.contracts.get('MetaForwarder')
const v2Calculations = await hre.deployments.get('V2Calculations')



await hre.upgrades.proposeBatchTimelock({
title: 'TellerV2: Protocol Trusted Forwarder ',
description: `
# TellerV2

* Adds support for improved trusted forwarder.
`,
_steps: [
{
proxy: tellerV2,
implFactory: await hre.ethers.getContractFactory('TellerV2', {
libraries: {
V2Calculations: v2Calculations.address,
},
}),

opts: {
unsafeSkipStorageCheck: true,
unsafeAllow: [
'constructor',
'state-variable-immutable',
'external-library-linking',
],
constructorArgs: [await metaForwarder.getAddress()],
},
},
],
})

hre.log('done.')
hre.log('')
hre.log('----------')

return true
}

// tags and deployment
deployFn.id = 'teller-v2:context-forwarding-upgrade'
deployFn.tags = [
'proposal',
'upgrade',
'teller-v2',
'teller-v2:context-forwarding-upgrade',
]
deployFn.dependencies = ['teller-v2:deploy']
deployFn.skip = async (hre) => {
return !hre.network.live || !['goerli', 'polygon'].includes(hre.network.name)
}
export default deployFn
Loading