Skip to content

Commit

Permalink
Merge pull request #111 from CirclesUBI/20240222-group-mint
Browse files Browse the repository at this point in the history
group mint
  • Loading branch information
jaensen authored Mar 6, 2024
2 parents 0200e48 + 67b1d3c commit 3d0906d
Show file tree
Hide file tree
Showing 14 changed files with 521 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Run Forge build
run: |
forge --version
forge build --sizes
forge build
id: build

- name: Run Forge tests
Expand Down
4 changes: 0 additions & 4 deletions remappings.txt

This file was deleted.

3 changes: 2 additions & 1 deletion src/circles/DiscountedBalances.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ contract DiscountedBalances {

/**
* @dev stores the discounted balances of the accounts privately.
* Mapping from Circles identifiers to accounts to the discounted balance.
*/
mapping(uint256 id => mapping(address account => DiscountedBalance)) private discountedBalances;
mapping(uint256 => mapping(address => DiscountedBalance)) private discountedBalances;

/**
* @dev Store a lookup table T(n) for computing issuance.
Expand Down
4 changes: 2 additions & 2 deletions src/graph/Graph.sol
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ contract Graph is ProxyFactory, IGraph {
function registerAvatar() external notOnTrustGraph(msg.sender) {
bytes memory avatarCircleNodeSetupData = abi.encodeWithSelector(AVATAR_CIRCLE_SETUP_CALLPREFIX, msg.sender);
IAvatarCircleNode avatarCircleNode =
IAvatarCircleNode(address(createProxy(address(masterCopyAvatarCircleNode), avatarCircleNodeSetupData)));
IAvatarCircleNode(address(_createProxy(address(masterCopyAvatarCircleNode), avatarCircleNodeSetupData)));

avatarToCircle[msg.sender] = avatarCircleNode;
_insertAvatarCircleNode(avatarCircleNode);
Expand All @@ -246,7 +246,7 @@ contract Graph is ProxyFactory, IGraph {
bytes memory groupCircleNodeSetupData =
abi.encodeWithSelector(GROUP_CIRCLE_SETUP_CALLPREFIX, msg.sender, _exitFee_64x64);
IGroupCircleNode groupCircleNode =
IGroupCircleNode(address(createProxy(address(masterCopyGroupCircleNode), groupCircleNodeSetupData)));
IGroupCircleNode(address(_createProxy(address(masterCopyGroupCircleNode), groupCircleNodeSetupData)));

groupToCircle[msg.sender] = groupCircleNode;
_insertGroupCircleNode(groupCircleNode);
Expand Down
64 changes: 64 additions & 0 deletions src/groups/BaseMintPolicy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.13;

import "./IMintPolicy.sol";
import "./Definitions.sol";

abstract contract MintPolicy is IMintPolicy {
// External functions

/**
* @notice Simple mint policy that always returns true
*/
function beforeMintPolicy(
address, /*_minter*/
address, /*_group*/
address[] calldata, /*_collateral*/
uint256[] calldata, /*_amounts*/
bytes calldata /*_data*/
) external virtual override returns (bool) {
return true;
}

/**
* @notice Simple burn policy that always returns true
*/
function beforeBurnPolicy(address, address, uint256, bytes calldata) external virtual override returns (bool) {
return true;
}

/**
* @notice Simple redeem policy that returns the redemption ids and values as requested in the data
* @param _data Optional data bytes passed to redeem policy
*/
function beforeRedeemPolicy(
address, /*_operator*/
address, /*_redeemer*/
address, /*_group*/
uint256, /*_value*/
bytes calldata _data
)
external
virtual
override
returns (
uint256[] memory _ids,
uint256[] memory _values,
uint256[] memory _burnIds,
uint256[] memory _burnValues
)
{
// simplest policy is to return the collateral as the caller requests it in data
BaseMintPolicyDefinitions.BaseRedemptionPolicy memory redemption =
abi.decode(_data, (BaseMintPolicyDefinitions.BaseRedemptionPolicy));

// and no collateral gets burnt upon redemption
_burnIds = new uint256[](0);
_burnValues = new uint256[](0);

// standard treasury checks whether the total sums add up to the amount of group Circles redeemed
// so we can simply decode and pass the request back to treasury.
// The redemption will fail if it does not contain (sufficient of) these Circles
return (redemption.redemptionIds, redemption.redemptionValues, _burnIds, _burnValues);
}
}
14 changes: 14 additions & 0 deletions src/groups/Definitions.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.13;

contract BaseMintPolicyDefinitions {
// Type declarations

/**
* @notice Base redemption policy to user specify desired collateral to redeem
*/
struct BaseRedemptionPolicy {
uint256[] redemptionIds;
uint256[] redemptionValues;
}
}
25 changes: 25 additions & 0 deletions src/groups/IMintPolicy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.13;

interface IMintPolicy {
function beforeMintPolicy(
address minter,
address group,
address[] calldata collateral,
uint256[] calldata amounts,
bytes calldata data
) external returns (bool);

function beforeRedeemPolicy(address operator, address redeemer, address group, uint256 value, bytes calldata data)
external
returns (
uint256[] memory redemptionIds,
uint256[] memory redemptionValues,
uint256[] memory burnIds,
uint256[] memory burnValues
);

function beforeBurnPolicy(address burner, address group, uint256 value, bytes calldata data)
external
returns (bool);
}
Loading

0 comments on commit 3d0906d

Please sign in to comment.