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

chore: redeployed, reconciled conflicts, added owner/deployer factory exception #50

Merged
merged 11 commits into from
Oct 30, 2023
3 changes: 2 additions & 1 deletion contracts/AutID.sol
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ contract AutID is ERC2771Recipient, ERC721URIStorageUpgradeable, IAutID {
require(newCommitment > 0 && newCommitment < 11, "AutID: Commitment should be between 1 and 10");

require(
newCommitment >= INovaCommitment(daoAddress).getCommitment(), "Commitment lower than the DAOs min commitment"
newCommitment >= INovaCommitment(daoAddress).getCommitment(),
"Commitment lower than the DAOs min commitment"
);

holderToDAOMembershipData[_msgSender()][daoAddress].commitment = newCommitment;
Expand Down
4 changes: 4 additions & 0 deletions contracts/ILocalReputation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@ interface ILocalReputation {
) external pure returns (uint256 score);

function bulkPeriodicUpdate(address group_) external returns (uint256[] memory localReputationScores);

function pointsPerInteraction(uint256 interactionContextID) external view returns (uint16 points);

function interactionID(address plugin_, bytes memory data_) external view returns (uint256 id);
}
7 changes: 1 addition & 6 deletions contracts/components/abstracts/NovaArchetype.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@ abstract contract NovaArchetype is INovaArchetype {
archetype = parameter;
}

function _setWeightFor(
uint8 parameter,
uint256 value
)
internal
{
function _setWeightFor(uint8 parameter, uint256 value) internal {
_validateParameter(parameter);
weightFor[parameter] = value;
}
Expand Down
20 changes: 10 additions & 10 deletions contracts/components/abstracts/NovaTrifolds.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

/**
Not yet included to the Nova instnace
* Not yet included to the Nova instnace
*/

contract NovaTrifolds is ERC721 {
Expand All @@ -26,7 +26,7 @@ contract NovaTrifolds is ERC721 {
TNode[] internal _graph;
mapping(uint64 => uint64[]) internal _nodeUplinkExpJumps;

address immutable public nova;
address public immutable nova;

constructor(address nova_, string memory name_, string memory symbol_) ERC721(name_, symbol_) {
TNode memory node;
Expand All @@ -35,7 +35,7 @@ contract NovaTrifolds is ERC721 {
_mint(_msgSender(), 0);
}

/// @dev set associated hash
/// @dev set associated hash
function _setIpfsHash(uint64 authorization, uint64 to, bytes32 ipfsHash) internal {
require(to < _graph.length);
require(ipfsHash != bytes32(0));
Expand Down Expand Up @@ -65,40 +65,40 @@ contract NovaTrifolds is ERC721 {
_fillUplinkExpJumps(length);
emit NodeAdded(length, to, uint8(ENodeType.Trifold), ipfsHash, sender);

for (uint i; i != 3; ++i) {
for (uint256 i; i != 3; ++i) {
cuspNodes[i].depth = trifoldNode.depth + 1;
cuspNodes[i].uplink = length;
cuspNodes[i].nodeType = uint8(ENodeType.Cusp);
cuspNodes[i].ipfsHash = roles[i];
_graph.push(cuspNodes[i]);
ERC721._mint(sender, length + i + 1);

emit NodeAdded(length + uint64(i) + 1, length, uint8(ENodeType.Cusp), ipfsHash, sender);
}
}

/// @dev fill an array of ancestors at 2^i distances
/// @dev fill an array of ancestors at 2^i distances
function _fillUplinkExpJumps(uint64 to) internal {
TNode memory node = _graph[to];
uint64[64] memory jumps;
uint256 count;
uint64 curNodeId = to;
for(; (1 << count) < node.depth; ++count) {
for (; (1 << count) < node.depth; ++count) {
uint256 targetDepth = node.depth - (1 << count);
while(_graph[curNodeId].depth != targetDepth) {
while (_graph[curNodeId].depth != targetDepth) {
curNodeId = _graph[curNodeId].uplink;
}
jumps[count] = curNodeId;
}
uint64[] memory jumpsCut = new uint64[](count);
for(uint256 i; i != count; ++i) {
for (uint256 i; i != count; ++i) {
jumpsCut[i] = jumps[i];
}
_nodeUplinkExpJumps[to] = jumpsCut;
}

/// @dev checks if `to` node descends to `from` node
function _checkUplink(uint64 from, uint64 to) internal view returns(bool) {
function _checkUplink(uint64 from, uint64 to) internal view returns (bool) {
TNode memory fromNode = _graph[from];
TNode memory toNode = _graph[to];
while (fromNode.depth < toNode.depth) {
Expand Down
4 changes: 2 additions & 2 deletions contracts/components/interfaces/get/INovaArchetype.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface INovaArchetype {
event MainArchetypeSet(uint8);
event ArchetypeWeightSet(uint8, uint256);

function archetype() external view returns(uint8);
function archetype() external view returns (uint8);

function weightFor(uint8) external view returns(uint256);
function weightFor(uint8) external view returns (uint256);
}
1 change: 0 additions & 1 deletion contracts/components/interfaces/set/INovaArchetypeSet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity 0.8.19;

interface INovaArchetypeSet {

function setArchetype(uint8) external;

function setWeightFor(uint8, uint256) external;
Expand Down
2 changes: 1 addition & 1 deletion contracts/expander/DAOExpander.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import "../components/abstracts/NovaModules.sol";
import "../components/abstracts/NovaMetadata.sol";
import "../components/abstracts/NovaCommitment.sol";
import "../components/abstracts/NovaMarket.sol";
import "../components/interfaces/get/INovaMembership.sol"; // todo: rename to `INovaMembers.sol`
import "../components/interfaces/get/INovaMembership.sol"; // todo: rename to `INovaMembers.sol`
import "../components/abstracts/AutIDAddress.sol";
import "../expander/interfaces/IDAOExpander.sol";
import "../modules/onboarding/OnboardingModule.sol";
Expand Down
10 changes: 1 addition & 9 deletions contracts/nova/Nova.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,7 @@ import "./interfaces/INova.sol";
/// @title Nova
/// @notice
/// @dev
contract Nova is
NovaUpgradeable,
NovaMembers,
NovaMetadata,
NovaUrls,
NovaMarket,
NovaModules,
NovaCommitment
{
contract Nova is NovaUpgradeable, NovaMembers, NovaMetadata, NovaUrls, NovaMarket, NovaModules, NovaCommitment {
uint256[50] private __basesGap;

address public deployer;
Expand Down
65 changes: 15 additions & 50 deletions contracts/nova/NovaRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,24 @@ import {INovaRegistry} from "./interfaces/INovaRegistry.sol";
import {IAllowlist} from "../utils/IAllowlist.sol";
import {Nova} from "../nova/Nova.sol";

/// @title NovaRegistry
/// @title NovaRegistry
contract NovaRegistry is INovaRegistry, ERC2771Recipient, Ownable {
event NovaDeployed(address);

// just for interface compatibility
// just for interface compatibility
// actually there is no need to store it in the contract
mapping(address => address[]) novaDeployers;
mapping(address => address[]) novaDeployers;
address[] public novas;

address public immutable autIDAddr;
address public immutable pluginRegistry;
UpgradeableBeacon immutable public upgradeableBeacon;
UpgradeableBeacon public immutable upgradeableBeacon;
IAllowlist public allowlist;

// don't know why it's here but it was in the previous version
address deployerAddress;

constructor(
address trustedForewarder,
address autIDAddr_,
address novaLogic,
address pluginRegistry_
)
Ownable()
{
constructor(address trustedForewarder, address autIDAddr_, address novaLogic, address pluginRegistry_) Ownable() {
require(trustedForewarder != address(0), "NovaRegistry: trustedForewarder address zero");
require(autIDAddr_ != address(0), "NovaRegistry: AutID address zero");
require(novaLogic != address(0), "NovaRegistry: Nova logic address zero");
Expand All @@ -54,34 +47,22 @@ contract NovaRegistry is INovaRegistry, ERC2771Recipient, Ownable {
// the only reason for this function is to keep interface compatible with sdk
// `novas` variable is public anyway
// the only reason for `novas` variable is that TheGraph is not connected
function getNovas() public view returns(address[] memory) {
function getNovas() public view returns (address[] memory) {
return novas;
}

// the same comment as for `getNovas` method
function getNovaByDeployer(address deployer) public view returns(address[] memory) {
function getNovaByDeployer(address deployer) public view returns (address[] memory) {
return novaDeployers[deployer];
}

/// @dev depoloy beacon proxy for a new nova
function deployNova(
uint256 market,
string memory metadata,
uint256 commitment
)
external
returns(address nova)
{
_validateNovaDeploymentParams(
market,
metadata,
commitment
);
function deployNova(uint256 market, string memory metadata, uint256 commitment) external returns (address nova) {
_validateNovaDeploymentParams(market, metadata, commitment);
_checkAllowlist();

bytes memory data = abi.encodeWithSelector(
Nova.initialize.selector,
_msgSender(), autIDAddr, market, metadata, commitment, pluginRegistry
Nova.initialize.selector, _msgSender(), autIDAddr, market, metadata, commitment, pluginRegistry
);
nova = address(new BeaconProxy(address(upgradeableBeacon), data));
novaDeployers[_msgSender()].push(nova);
Expand Down Expand Up @@ -109,6 +90,7 @@ contract NovaRegistry is INovaRegistry, ERC2771Recipient, Ownable {
}

function _checkAllowlist() internal view {
if (_msgSender() == deployerAddress || _msgSender() == upgradeableBeacon.owner()) return;
if (address(allowlist) != address(0)) {
if (!allowlist.isAllowed(_msgSender())) {
revert IAllowlist.Unallowed();
Expand All @@ -121,36 +103,19 @@ contract NovaRegistry is INovaRegistry, ERC2771Recipient, Ownable {
}
}

// no idea why `autIDAddr` and `pluginRegistrty` are passed
// no idea why `autIDAddr` and `pluginRegistrty` are passed
// i'm leavin it as it is in order to maintain compativility with sdk
function _validateNovaDeploymentParams(
uint256 market,
string memory metadata,
uint256 commitment
)
internal
pure
{
function _validateNovaDeploymentParams(uint256 market, string memory metadata, uint256 commitment) internal pure {
require(market > 0 && market < 4, "NovaRegistry: invalid market value");
require(bytes(metadata).length != 0, "NovaRegistry: metadata empty");
require(commitment > 0 && commitment < 11, "NovaRegistry: invalid commitment value");
}

function _msgSender()
internal
override(ERC2771Recipient, Context)
view
returns(address)
{
function _msgSender() internal view override(ERC2771Recipient, Context) returns (address) {
return ERC2771Recipient._msgSender();
}

function _msgData()
internal
override(ERC2771Recipient, Context)
view
returns(bytes calldata)
{
function _msgData() internal view override(ERC2771Recipient, Context) returns (bytes calldata) {
return ERC2771Recipient._msgData();
}
}
7 changes: 3 additions & 4 deletions contracts/nova/NovaUpgradeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
abstract contract NovaUpgradeable is Initializable {
// 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50
bytes32 private constant _BEACON_SLOT = bytes32(uint256(keccak256("eip1967.proxy.beacon")));
bytes32 private constant _IMPLEMENTATION_SLOT =
bytes32(uint256(keccak256("id.aut.os.proxy.implementation")) - 1);
bytes32 private constant _IMPLEMENTATION_SLOT = bytes32(uint256(keccak256("id.aut.os.proxy.implementation")) - 1);

function implementation() external view returns(address) {
function implementation() external view returns (address) {
return _getImplementationSlot().value;
}

function beacon() external view returns(address) {
function beacon() external view returns (address) {
return _getBeaconSlot().value;
}

Expand Down
50 changes: 50 additions & 0 deletions contracts/plugins/interactions/OffchainTaskWithRep.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//SPDX-License-Identifier: UNLICENCED
pragma solidity 0.8.19;

import {OpenTaskPlugin} from "../tasks/OpenTaskPlugin.sol";
import {InteractionModifier} from "./InteractionModifier.sol";
import {ILocalReputation} from "../../ILocalReputation.sol";

import {IPluginRegistry} from "../registry/IPluginRegistry.sol";

import {INova} from "../../nova/interfaces/INova.sol";

contract OffchainTaskWithRep is OpenTaskPlugin, InteractionModifier {
constructor(address nova_) OpenTaskPlugin(nova_, true) InteractionModifier(nova_) {
ILR = ILocalReputation(IPluginRegistry(INova(nova_).pluginRegistry()).defaultLRAddr());
ILR.initialize(nova_);
}

function finalizeFor(uint256 taskId, address submitter)
public
override
isAsInteraction(abi.encodeWithSelector(msg.sig, taskId), submitter)
atStatus(taskId, submitter, TaskStatus.Submitted)
onlyCreator(taskId)
{
super.finalizeFor(taskId, submitter);
}

/// @notice the creator of the task can use to set number of points to be awared for finalizing a task
/// @param taskID ID of task to assign points balance to
/// @param pointsWeight how many points the task will be worth
function setWeightForTask(uint256 taskID, uint16 pointsWeight) external onlyCreator(taskID) {
bytes memory dataTaskCall = abi.encodeWithSelector(this.finalizeFor.selector, taskID);
bytes[] memory bts = new bytes[](1);
uint16[] memory pts = new uint16[](1);
bts[0] = dataTaskCall;
pts[0] = pointsWeight;

ILR.setInteractionWeights(address(this), bts, pts);
}

/// @notice retrieves the amount of points associated with provided task id
/// @param taskID identifier of task ID
function getRepPointsOfTask(uint256 taskID) external view returns (uint256) {
return uint256(
ILR.pointsPerInteraction(
ILR.interactionID(address(this), abi.encodeWithSelector(this.finalizeFor.selector, taskID))
)
);
}
}
23 changes: 23 additions & 0 deletions contracts/plugins/interactions/OpenTaskWithRep.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,27 @@ contract OpenTaskWithRep is OpenTaskPlugin, InteractionModifier {
{
super.finalizeFor(taskId, submitter);
}

/// @notice the creator of the task can use to set number of points to be awared for finalizing a task
/// @param taskID ID of task to assign points balance to
/// @param pointsWeight how many points the task will be worth
function setWeightForTask(uint256 taskID, uint16 pointsWeight) external onlyCreator(taskID) {
bytes memory dataTaskCall = abi.encodeWithSelector(this.finalizeFor.selector, taskID);
bytes[] memory bts = new bytes[](1);
uint16[] memory pts = new uint16[](1);
bts[0] = dataTaskCall;
pts[0] = pointsWeight;

ILR.setInteractionWeights(address(this), bts, pts);
}

/// @notice retrieves the amount of points associated with provided task id
/// @param taskID identifier of task ID
function getRepPointsOfTask(uint256 taskID) external view returns (uint256) {
return uint256(
ILR.pointsPerInteraction(
ILR.interactionID(address(this), abi.encodeWithSelector(this.finalizeFor.selector, taskID))
)
);
}
}
Loading
Loading