Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
ethereumdegen committed Nov 8, 2024
1 parent 43bae3e commit a7af2d6
Show file tree
Hide file tree
Showing 7 changed files with 822 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Contracts
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

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 "../../../libraries/NumbersLib.sol";

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

import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";

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

contract LenderCommitmentGroupFactory is OwnableUpgradeable {
using AddressUpgradeable for address;
using NumbersLib for uint256;


//this is the beacon proxy
address public lenderGroupBeacon;


mapping(address => uint256) public deployedLenderGroupContracts;

event DeployedLenderGroupContract(address indexed groupContract);



function initialize(address _lenderGroupBeacon )
external
initializer
{
lenderGroupBeacon = _lenderGroupBeacon;
__Ownable_init_unchained();
}


/*
This should deploy a new lender commitment group pool contract.
It will use create commitment args in order to define the pool contracts parameters such as its primary principal token.
Shares will be distributed at a 1:1 ratio of the primary principal token so if 1e18 raw WETH are deposited, the depositor gets 1e18 shares for the group pool.
*/
function deployLenderCommitmentGroupPool(
uint256 _initialPrincipalAmount,
ILenderCommitmentGroup.CommitmentGroupConfig calldata _commitmentGroupConfig,
IUniswapPricingLibrary.PoolRouteConfig[] calldata _poolOracleRoutes
) external returns (address newGroupContract_) {



BeaconProxy newGroupContract_ = new BeaconProxy(
lenderGroupBeacon,
abi.encodeWithSelector(
ILenderCommitmentGroup.initialize.selector, //this initializes
_commitmentGroupConfig,
_poolOracleRoutes

)
);

deployedLenderGroupContracts[address(newGroupContract_)] = block.number; //consider changing this ?
emit DeployedLenderGroupContract(address(newGroupContract_));



//it is not absolutely necessary to have this call here but it allows the user to potentially save a tx step so it is nice to have .
if (_initialPrincipalAmount > 0) {
//should pull in the creators initial committed principal tokens .

//send the initial principal tokens to _newgroupcontract here !
// so it will have them for addPrincipalToCommitmentGroup which will pull them from here

_addPrincipalToCommitmentGroup(
address(newGroupContract_),
_initialPrincipalAmount,
_commitmentGroupConfig.principalTokenAddress

);


}


//transfer ownership to msg.sender
OwnableUpgradeable(address(newGroupContract_))
.transferOwnership(msg.sender);
}



function _addPrincipalToCommitmentGroup(
address _newGroupContract,
uint256 _initialPrincipalAmount,
address _principalTokenAddress
) internal {


IERC20(_principalTokenAddress).transferFrom(
msg.sender,
address(this),
_initialPrincipalAmount
);
IERC20(_principalTokenAddress).approve(
_newGroupContract,
_initialPrincipalAmount
);

address sharesRecipient = msg.sender;

uint256 sharesAmount_ = ILenderCommitmentGroup(address(_newGroupContract))
.addPrincipalToCommitmentGroup(
_initialPrincipalAmount,
sharesRecipient,
0 //_minShares
);


}

}
147 changes: 147 additions & 0 deletions packages/contracts/contracts/oracleprotection/HypernativeOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";

contract HypernativeOracle is AccessControl {
struct OracleRecord {
uint256 registrationTime;
bool isPotentialRisk;
}

bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
bytes32 public constant CONSUMER_ROLE = keccak256("CONSUMER_ROLE");
uint256 internal threshold = 2 minutes;

mapping(bytes32 /*hashedAccount*/ => OracleRecord) internal accountHashToRecord;

event ConsumerAdded(address consumer);
event ConsumerRemoved(address consumer);
event Registered(address consumer, address account);
event Whitelisted(bytes32[] hashedAccounts);
event Allowed(bytes32[] hashedAccounts);
event Blacklisted(bytes32[] hashedAccounts);
event TimeThresholdChanged(uint256 threshold);

modifier onlyAdmin() {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Hypernative Oracle error: admin required");
_;
}

modifier onlyOperator() {
require(hasRole(OPERATOR_ROLE, msg.sender), "Hypernative Oracle error: operator required");
_;
}

modifier onlyConsumer {
require(hasRole(CONSUMER_ROLE, msg.sender), "Hypernative Oracle error: consumer required");
_;
}

constructor(address _admin) {
_grantRole(DEFAULT_ADMIN_ROLE, _admin);
}

function register(address _account) external onlyConsumer() {
bytes32 _hashedAccount = keccak256(abi.encodePacked(_account, address(this)));
require(accountHashToRecord[_hashedAccount].registrationTime == 0, "Account already registered");
accountHashToRecord[_hashedAccount].registrationTime = block.timestamp;
emit Registered(msg.sender, _account);
}

function registerStrict(address _account) external onlyConsumer() {
bytes32 _hashedAccount = keccak256(abi.encodePacked(_account, address(this)));
require(accountHashToRecord[_hashedAccount].registrationTime == 0, "Account already registered");
accountHashToRecord[_hashedAccount].registrationTime = block.timestamp;
accountHashToRecord[_hashedAccount].isPotentialRisk = true;
emit Registered(msg.sender, _account);
}

// **
// * @dev Operator only function, can be used to whitelist accounts in order to pre-approve them
// * @param hashedAccounts array of hashed accounts
// */
function whitelist(bytes32[] calldata hashedAccounts) public onlyOperator() {
for (uint256 i; i < hashedAccounts.length; i++) {
accountHashToRecord[hashedAccounts[i]].registrationTime = 1;
accountHashToRecord[hashedAccounts[i]].isPotentialRisk = false;
}
emit Whitelisted(hashedAccounts);
}

// **
// * @dev Operator only function, can be used to blacklist accounts in order to prevent them from interacting with the protocol
// * @param hashedAccounts array of hashed accounts
// */
function blacklist(bytes32[] calldata hashedAccounts) public onlyOperator() {
for (uint256 i; i < hashedAccounts.length; i++) {
accountHashToRecord[hashedAccounts[i]].isPotentialRisk = true;
}
emit Blacklisted(hashedAccounts);
}

// **
// * @dev Operator only function, when strict mode is being used, this function can be used to allow accounts to interact with the protocol
// * @param hashedAccounts array of hashed accounts
// */
function allow(bytes32[] calldata hashedAccounts) public onlyOperator() {
for (uint256 i; i < hashedAccounts.length; i++) {
accountHashToRecord[hashedAccounts[i]].isPotentialRisk = false;
}
emit Allowed(hashedAccounts);
}

/**
* @dev Admin only function, can be used to block any interaction with the protocol, meassured in seconds
*/
function changeTimeThreshold(uint256 _newThreshold) public onlyAdmin() {
require(_newThreshold >= 2 minutes, "Threshold must be greater than 2 minutes");
threshold = _newThreshold;
emit TimeThresholdChanged(threshold);
}

function addConsumers(address[] memory consumers) public onlyAdmin() {
for (uint256 i; i < consumers.length; i++) {
_grantRole(CONSUMER_ROLE, consumers[i]);
emit ConsumerAdded(consumers[i]);
}
}

function revokeConsumers(address[] memory consumers) public onlyAdmin() {
for (uint256 i; i < consumers.length; i++) {
_revokeRole(CONSUMER_ROLE, consumers[i]);
emit ConsumerRemoved(consumers[i]);
}
}

function addOperator(address operator) public onlyAdmin() {
_grantRole(OPERATOR_ROLE, operator);
}

function revokeOperator(address operator) public onlyAdmin() {
_revokeRole(OPERATOR_ROLE, operator);
}

function changeAdmin(address _newAdmin) public onlyAdmin() {
_grantRole(DEFAULT_ADMIN_ROLE, _newAdmin);
_revokeRole(DEFAULT_ADMIN_ROLE, msg.sender);
}

//if true, the account has been registered for two minutes
function isTimeExceeded(address account) external onlyConsumer() view returns (bool) {
bytes32 hashedAccount = keccak256(abi.encodePacked(account, address(this)));
require(accountHashToRecord[hashedAccount].registrationTime != 0, "Account not registered");
return block.timestamp - accountHashToRecord[hashedAccount].registrationTime > threshold;
}

function isBlacklistedContext(address _origin, address _sender) external onlyConsumer() view returns (bool) {
bytes32 hashedOrigin = keccak256(abi.encodePacked(_origin, address(this)));
bytes32 hashedSender = keccak256(abi.encodePacked(_sender, address(this)));
return accountHashToRecord[hashedOrigin].isPotentialRisk || accountHashToRecord[hashedSender].isPotentialRisk;
}

function isBlacklistedAccount(address _account) external onlyConsumer() view returns (bool) {
bytes32 hashedAccount = keccak256(abi.encodePacked(_account, address(this)));
return accountHashToRecord[hashedAccount].isPotentialRisk;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IOracleProtectionManager} from "../interfaces/oracleprotection/IOracleProtectionManager.sol";

abstract contract OracleProtectedChild {
address public immutable ORACLE_MANAGER;


modifier onlyOracleApproved() {

IOracleProtectionManager oracleManager = IOracleProtectionManager(ORACLE_MANAGER);
require( oracleManager .isOracleApproved(msg.sender ) , "Oracle: Not Approved");
_;
}

modifier onlyOracleApprovedAllowEOA() {

IOracleProtectionManager oracleManager = IOracleProtectionManager(ORACLE_MANAGER);
require( oracleManager .isOracleApprovedAllowEOA(msg.sender ) , "Oracle: Not Approved");
_;
}

constructor(address oracleManager){
ORACLE_MANAGER = oracleManager;
}

}
Loading

0 comments on commit a7af2d6

Please sign in to comment.