Skip to content

Commit

Permalink
Complexity reduction session with Martin, Daniel, Ingo and Ben
Browse files Browse the repository at this point in the history
Co-authored-by: Martin Köppelmann <[email protected]>
Co-authored-by: Daniel Janz <[email protected]>
Co-authored-by: Ingo Collatz <[email protected]>
  • Loading branch information
4 people committed Jan 30, 2024
1 parent 3a2bcfc commit 7975a45
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 33 deletions.
6 changes: 4 additions & 2 deletions src/graph/Graph.sol
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ contract Graph is ProxyFactory, IGraph {
uint256[] calldata _flow,
bytes calldata _packedCoordinates
) public {
// todo: sender does not have to be registered; can be anyone
// first unpack the coordinates to array of uint16
uint16[] memory coordinates = _unpackCoordinates(_packedCoordinates, _flow.length);

Expand Down Expand Up @@ -431,9 +432,9 @@ contract Graph is ProxyFactory, IGraph {
}

function operateFlowMatrix(
int256[] calldata _intendedNettedFlow,
int256[] calldata _transferIntents,
address[] calldata _flowVertices,
uint256[] calldata _flow,
uint256[] calldata _flow, // consider adding a group mint targets array
bytes calldata _packedCoordinates
) public {
// first unpack the coordinates to array of uint16
Expand All @@ -445,6 +446,7 @@ contract Graph is ProxyFactory, IGraph {
);

// check that all flow vertices have the calling operator enabled.
// todo: only check for net-senders
require(isGraphOperatorForSet(msg.sender, _flowVertices), "Graph operator must be enabled for all vertices.");

// if each vertex in the intended netted flow is zero, then it is a closed path
Expand Down
31 changes: 0 additions & 31 deletions src/multitoken-graph/Graph.sol

This file was deleted.

210 changes: 210 additions & 0 deletions src/multitoken-graph/Hub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.13;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

contract Graph is ERC1155 {
// Constants

// People registering can mint up to one Circle per hour.
// todo: should this be implemented without branching, ie. all be contracts
address public constant PERSONAL_MINT = address(0x1);

// Organizations can register with a no-mint policy.
address public constant NO_MINT = address(0x2);

address public constant SENTINEL = address(0x1);

// State variables

// Standard mint for Circle groups.
address public immutable standardGroupMint;

// linked list for registered avatars, used by all people,
// groups and organizations.
mapping(address => address) public avatars;

mapping(address => uint256) public lastMintTimes;

mapping(address => bool) public stopped;

// Mint policy registered by avatar.
mapping(address => address) public mintPolicies;

mapping(address => address) public treasuries;

// todo: ok for linked list, expiry 96 bits
mapping(address => mapping(address => uint256)) public trustMarkers;

// todo: do address
mapping(uint256 => bytes32) public avatarIpfsUris;

// Modifiers

modifier isHuman(address _human) {
require(
lastMintTimes[_human] > 0,
""
);
_;
}

modifier isGroup(address _group) {
require(
mintPolicies[_group] != address(0),
""
);
_;
}

modifier isOrganization(address _organization) {
require(
avatars[_organization] != address(0) &&
mintPolicies[_organization] == address(0) &&
lastMintTimes[_organization] == uint256(0),
""
);
_;
}


// Constructor

constructor(address _standardGroupMint) ERC1155("https://fallback.aboutcircles.com/v1/profile/{id}.json") {
standardGroupMint = _standardGroupMint;
}

// External functions

function registerHuman() external {
require(trusts(_inviter, msg.sender), "");
// todo: v1 stopped & enable migration
require(...);
insertAvatar(msg.sender);
// mintPolicies[msg.sender] = PERSONAL_MINT;
lastMintTimes[msg.sender] = block.timestamp;
// treasuries[msg.sender] = address(0);

// todo: let's welcome mint re-introduced; 3 days not demurraged
}

function registerGroup(address _treasury, string _name, string _symbol) {
_registerGroup(msg.sender, standardGroupMint, _treasury);
}

function registerCustomGroup(address _mint, address _treasury) external {
// msg.sender controls membership
// minting: policy only
// redemption: treasury contract (ideally generated from a factory - outside protocol)
require(...);
_registerGroup(msg.sender, _mint, _treasury);
}

function registerOrganization(string _name) {
insertAvatar(msg.sender);
lastMintTimes[msg.sender] = 0;
}


function trust(address _trustReceiver, uint256 _expiry) external {
// todo: make iterable; don't require expiry > block.timestamp
// possibly: if _expiry < block.timestamp, set expiry = block.timestamp;
trustMarkers[msg.sender][_trustReceiver] = _expiry;
}

// todo: happy with this name?
function personalMint() external isHuman(msg.sender) {
// do daily demurrage over claimable period; max 2week

}

// graph transfers SHOULD allow personal -> group conversion en route

// msg.sender holds collateral, and MUST be accepted by group
// maybe less
function groupMint(address _group, address[] calldata _collateral, uint256[] calldata _amounts) {
// check group and collateral exist
// de-demurrage amounts
// loop over collateral

require(
mintPolicies[_group].beforeMintPolicy(msg.sender, _group, _collateral, _amounts), "");

sendBatchTransfer(to: _group.treasury) // treasury.on1155Received should only implement but nothing protocol related

_mint(msg.sender, _group, sumAmounts);
}

// check if path transfer can be fully ERC1155 compatible
// note: matrix math needs to consider mints, otherwise it won't add up

function singleSourcePathTransfer() {
require(msg.sender == _source)
// todo: sender does not have to be registered; can be anyone
// can have multiple receivers
// can allow zero-nett amounts, ie. closed paths are ok

// consider adding a group mint targets array

// emit Transfer intent events
}

function operatorPathTransfer() {
// msg.sender = oeprator
require("nett sources have approved operator");
}

function wrapInflationaryERC20() {
// pass on name() but not modified
}

function unwrapInflationaryERC20() {

}

function wrapDemurrageERC20() {
// call on Hub for demurrage calculation in ERC20 contract

// dont do a global allowance; but do do an ERC20Permit

// do do a auto-factory of deterministic contract address
// and how?
}

// do some unique name hash finding for personal circles
// register with a salt for avoiding malicious blockage

function uri(uint256 _id) external view override returns (string memory uri_) {
if (avatarIpfsUris[_id] != bytes32(0)) {
return uri_ = string(abi.encodedPacked("ipfs://f0", bytes32ToHex(avatarIpfsUris[_id]);
} else {
return super.
}
}

function setUri(bytes32 _ipfsCid) external {
// msg.sender -> tokenId
avatarIpfsUris[uint256(msg.sender)] = _ipfsCid;
}


// Internal functions

function toDemurrageAmount(uint256 _amount, uint256 _timestamp) {
// timestamp should be "stepfunction" the timestamp
// todo: ask where the best time step is

if (_time<hubV1start) {_time = block.timestamp}

// uint256 durationSinceStart = _time - hubV1start;
// do conversion
}

function ToInflationAmount(uint256 _amount, uint256 _timestamp) {

}

function _registerGroup(address _avatar, address _mint, address _treasury, string _name, string _symbol) internal {
// do
}
}
1 change: 1 addition & 0 deletions src/proxy/Proxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ contract Proxy {
masterCopy = _masterCopy;
}

// todo: consider removing payable
fallback() external payable {
_fallback();
}
Expand Down

0 comments on commit 7975a45

Please sign in to comment.