Skip to content
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/allo-v2.1"]
path = lib/allo-v2.1
url = https://github.com/allo-protocol/allo-v2.1.git
36 changes: 36 additions & 0 deletions compiler_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"language": "Solidity",
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"": [
"ast"
],
"*": [
"abi",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.legacyAssembly",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"evm.gasEstimates",
"evm.assembly"
]
}
},
"remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"strategies/=lib/allo-v2.1/contracts/strategies/",
"libraries/=lib/allo-v2.1/contracts/core/libraries/",
"solady/=lib/allo-v2.1/lib/solady/src/"
]
}
}
7 changes: 5 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ libs = ["lib"]
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options

remappings = [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/"
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"strategies/=lib/allo-v2.1/contracts/strategies/",
"libraries/=lib/allo-v2.1/contracts/core/libraries/",
"solady/=lib/allo-v2.1/lib/solady/src/",
]
1 change: 1 addition & 0 deletions lib/allo-v2.1
Submodule allo-v2.1 added at 258f3c
112 changes: 112 additions & 0 deletions src/HyperStrategy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {AccessControl} from "lib/allo-v2.1/lib/openzeppelin-contracts/contracts/access/AccessControl.sol";
import {BaseStrategy} from "strategies/BaseStrategy.sol";
import {IAllo} from "lib/allo-v2.1/contracts/core/interfaces/IAllo.sol";
import {IHypercertToken} from "./interfaces/IHypercertToken.sol";
import {IHyperfund} from "./interfaces/IHyperfund.sol";

contract HyperStrategy is AccessControl, BaseStrategy {
// Roles
bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");

// Interfaces
IHyperfund public hyperfund;
IHypercertToken public hypercertMinter;

// Events
event Donated(address donor, address token, uint256 amount, uint256 hypercertUnits);

// Errors
error NOOP();

function initialize(uint256 _poolId, bytes memory _data) external virtual override {
(address _manager, address _hyperfund) = abi.decode(_data, (address, address));

hyperfund = IHyperfund(_hyperfund);
hypercertMinter = IHypercertToken(hyperfund.hypercertMinter());

_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(MANAGER_ROLE, _manager);
__BaseStrategy_init(_poolId);
emit Initialized(_poolId, _data);
}

/// ===============================
/// ========= Constructor =========
/// ===============================
constructor(address _allo, string memory _name) BaseStrategy(_allo, _name) {}

/// @notice Allocate funds hyperfund and hyperstaker pools
/// @param _data The data to decode
/// @param _sender The sender
function _allocate(bytes memory _data, address _sender) internal virtual override onlyRole(MANAGER_ROLE) {
(address[] memory _recipients, uint256[] memory _amounts) = abi.decode(_data, (address[], uint256[]));

// Assert recipient and amounts length are equal
if (_recipients.length != _amounts.length) {
revert ARRAY_MISMATCH();
}

IAllo.Pool memory pool = allo.getPool(poolId);
for (uint256 i; i < _recipients.length; ++i) {
uint256 _amount = _amounts[i];
address _recipientAddress = _recipients[i];

_transferAmount(pool.token, _recipientAddress, _amount);

emit Allocated(_recipientAddress, _amount, pool.token, _sender);
}
}

function _afterIncreasePoolAmount(uint256 _amount) internal virtual override {
IAllo.Pool memory pool = allo.getPool(poolId);
uint256 hypercertFraction = hyperfund.hypercertId();
int256 multiplier = hyperfund.tokenMultipliers(pool.token);
uint256 units;
if (multiplier > 0) {
units = _amount * uint256(multiplier);
} else {
units = _amount / uint256(-multiplier);
}

uint256 availableSupply = hypercertMinter.unitsOf(hypercertFraction);
require(availableSupply >= units);
_mintFraction(tx.origin, units, hypercertFraction);
emit Donated(tx.origin, pool.token, _amount, units);
}

function _distribute(address[] memory _recipientIds, bytes memory _recipientAmounts, address _sender)
internal
virtual
override
{
revert NOOP();
}

function _getRecipientStatus(address) internal view virtual override returns (Status) {
revert NOOP();
}

function _isValidAllocator(address _allocator) internal view virtual override returns (bool) {}

function _registerRecipient(bytes memory _data, address _sender) internal virtual override returns (address) {}

function _getPayout(address _recipientId, bytes memory _data)
internal
view
virtual
override
returns (PayoutSummary memory)
{}

function _mintFraction(address account, uint256 units, uint256 hypercertId) internal {
uint256[] memory newallocations = new uint256[](2);
newallocations[0] = hypercertMinter.unitsOf(hypercertId) - units;
newallocations[1] = units;
hypercertMinter.splitFraction(account, hypercertId, newallocations);
}

receive() external payable {}
}
2 changes: 1 addition & 1 deletion src/interfaces/IHypercertToken.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;
pragma solidity ^0.8.18;

interface IHypercertToken {
/**
Expand Down
8 changes: 8 additions & 0 deletions src/interfaces/IHyperfund.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

interface IHyperfund {
function hypercertId() external view returns (uint256);
function tokenMultipliers(address token) external view returns (int256);
function hypercertMinter() external view returns (address);
}