Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
49555f7
initial gating
Aug 29, 2024
5697ee4
collateral validator gating
Aug 29, 2024
2e7761c
Update contracts/contracts/lib/LibSubnetActor.sol
cryptoAtwill Aug 29, 2024
43ee469
Update contracts/contracts/lib/LibSubnetActor.sol
cryptoAtwill Aug 29, 2024
d961819
review feedbacks
Aug 29, 2024
05d1095
Merge branch 'main' of protocol-github:consensus-shipyard/ipc into va…
Aug 30, 2024
9f00973
adding tests
Aug 30, 2024
7102a78
update gater interface
Sep 2, 2024
92a1dc4
update ipc
Sep 2, 2024
2cec1a7
Merge branch 'main' into validator-gating
cryptoAtwill Sep 2, 2024
374a7df
update test
Sep 3, 2024
6057dd8
Merge branch 'validator-gating' of protocol-github:consensus-shipyard…
Sep 3, 2024
e89c069
adding deployments and sample cli
Sep 3, 2024
4c6000c
lint
Sep 3, 2024
0bfa4ec
wip
Sep 5, 2024
cccf84e
adding tests
Sep 6, 2024
19d6158
ipc-cli update
Sep 9, 2024
07f7182
fix ci
Sep 9, 2024
80db07b
fix linked token error
Sep 9, 2024
4743a12
fix ci
Sep 9, 2024
4fc0e73
increase allowance instead of approve
Sep 10, 2024
3dcacd0
feat: add simple docs
karlem Sep 18, 2024
9388b24
fix: typo
karlem Sep 18, 2024
ee3a9a5
Merge branch 'validator-gating' into collateral-sourcing
raulk Sep 19, 2024
6d2cc3a
Merge branch 'main' into collateral-sourcing
raulk Sep 19, 2024
4c7e013
update comment
Sep 20, 2024
8e6e1e8
rename generic token
Sep 20, 2024
c997cba
merge with upstream
Sep 20, 2024
7f2cb84
fix rust naming
Sep 20, 2024
d91dc44
Update contracts/contracts/subnet/SubnetActorGetterFacet.sol
cryptoAtwill Sep 23, 2024
5e7fc74
finish renaming
Sep 23, 2024
b868fd1
Merge branch 'collateral-sourcing' of protocol-github:consensus-shipy…
Sep 23, 2024
012fa69
fix fmt
Sep 23, 2024
6626ee3
update review feedbacks
Sep 23, 2024
b3b3516
update comment
Sep 23, 2024
6a0e65c
update comment
Sep 23, 2024
7cc73c3
fmt
Sep 23, 2024
ea5e69a
feat(node): address review comments against #1130 (#1147)
raulk Sep 25, 2024
78443ea
more comments
Sep 25, 2024
71cae9f
improve comment.
raulk Sep 25, 2024
c6820a4
Merge branch 'main' into collateral-sourcing
raulk Sep 25, 2024
587552f
remove unnecessary error types.
raulk Sep 25, 2024
bdbbc6a
fix error checker
Sep 25, 2024
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
340 changes: 170 additions & 170 deletions contracts/.storage-layouts/GatewayActorModifiers.json

Large diffs are not rendered by default.

338 changes: 169 additions & 169 deletions contracts/.storage-layouts/GatewayDiamond.json

Large diffs are not rendered by default.

356 changes: 182 additions & 174 deletions contracts/.storage-layouts/SubnetActorDiamond.json

Large diffs are not rendered by default.

358 changes: 183 additions & 175 deletions contracts/.storage-layouts/SubnetActorModifiers.json

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions contracts/contracts/SubnetActorDiamond.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ import {IERC165} from "./interfaces/IERC165.sol";
import {GatewayCannotBeZero, NotGateway, InvalidSubmissionPeriod, InvalidCollateral, InvalidMajorityPercentage, InvalidPowerScale} from "./errors/IPCErrors.sol";
import {BATCH_PERIOD, MAX_MSGS_PER_BATCH} from "./structs/CrossNet.sol";
import {LibDiamond} from "./lib/LibDiamond.sol";
import {PermissionMode, SubnetID, SupplyKind, SupplySource} from "./structs/Subnet.sol";
import {PermissionMode, SubnetID, AssetKind, Asset} from "./structs/Subnet.sol";
import {SubnetIDHelper} from "./lib/SubnetIDHelper.sol";
import {LibStaking} from "./lib/LibStaking.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SupplySourceHelper} from "./lib/SupplySourceHelper.sol";
import {AssetHelper} from "./lib/AssetHelper.sol";
error FunctionNotFound(bytes4 _functionSelector);

contract SubnetActorDiamond {
SubnetActorStorage internal s;

using SubnetIDHelper for SubnetID;
using SupplySourceHelper for SupplySource;
using AssetHelper for Asset;

struct ConstructorParams {
uint256 minActivationCollateral;
Expand All @@ -33,7 +33,8 @@ contract SubnetActorDiamond {
ConsensusType consensus;
int8 powerScale;
PermissionMode permissionMode;
SupplySource supplySource;
Asset supplySource;
Asset collateralSource;
SubnetID parentId;
address validatorGater;
}
Expand Down Expand Up @@ -96,6 +97,7 @@ contract SubnetActorDiamond {
s.changeSet.startConfigurationNumber = LibStaking.INITIAL_CONFIGURATION_NUMBER;
// Set the supply strategy.
s.supplySource = params.supplySource;
s.collateralSource = params.collateralSource;

if (params.validatorGater != address(0)) {
s.validatorGater = params.validatorGater;
Expand Down
46 changes: 28 additions & 18 deletions contracts/contracts/gateway/GatewayManagerFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {SubnetActorGetterFacet} from "../subnet/SubnetActorGetterFacet.sol";
import {BURNT_FUNDS_ACTOR} from "../constants/Constants.sol";
import {IpcEnvelope} from "../structs/CrossNet.sol";
import {FvmAddress} from "../structs/FvmAddress.sol";
import {SubnetID, Subnet, SupplySource} from "../structs/Subnet.sol";
import {Membership, SupplyKind} from "../structs/Subnet.sol";
import {SubnetID, Subnet, Asset} from "../structs/Subnet.sol";
import {Membership, AssetKind} from "../structs/Subnet.sol";
import {AlreadyRegisteredSubnet, CannotReleaseZero, MethodNotAllowed, NotEnoughFunds, NotEnoughFundsToRelease, NotEnoughCollateral, NotEmptySubnetCircSupply, NotRegisteredSubnet, InvalidXnetMessage, InvalidXnetMessageReason} from "../errors/IPCErrors.sol";
import {LibGateway} from "../lib/LibGateway.sol";
import {SubnetIDHelper} from "../lib/SubnetIDHelper.sol";
Expand All @@ -16,31 +16,34 @@ import {FilAddress} from "fevmate/contracts/utils/FilAddress.sol";
import {ReentrancyGuard} from "../lib/LibReentrancyGuard.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {SupplySourceHelper} from "../lib/SupplySourceHelper.sol";
import {AssetHelper} from "../lib/AssetHelper.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

string constant ERR_CHILD_SUBNET_NOT_ALLOWED = "Subnet does not allow child subnets";

contract GatewayManagerFacet is GatewayActorModifiers, ReentrancyGuard {
using FilAddress for address payable;
using SubnetIDHelper for SubnetID;
using SupplySourceHelper for SupplySource;
using AssetHelper for Asset;
using EnumerableSet for EnumerableSet.Bytes32Set;

/// @notice register a subnet in the gateway. It is called by a subnet when it reaches the threshold stake
/// @dev The subnet can optionally pass a genesis circulating supply that would be pre-allocated in the
/// subnet from genesis (without having to wait for the subnet to be spawned to propagate the funds).
function register(uint256 genesisCircSupply) external payable {
function register(uint256 genesisCircSupply, uint256 collateral) external payable {
// If L2+ support is not enabled, only allow the registration of new
// subnets in the root
if (s.networkName.route.length + 1 >= s.maxTreeDepth) {
revert MethodNotAllowed(ERR_CHILD_SUBNET_NOT_ALLOWED);
}

if (msg.value < genesisCircSupply) {
revert NotEnoughFunds();
if (genesisCircSupply > 0) {
SubnetActorGetterFacet(msg.sender).supplySource().lock(genesisCircSupply);
}
if (collateral > 0) {
SubnetActorGetterFacet(msg.sender).collateralSource().lock(collateral);
Comment on lines +40 to +44
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would support dropping this feature entirely: #1142

}
uint256 collateral = msg.value - genesisCircSupply;

SubnetID memory subnetId = s.networkName.createSubnetId(msg.sender);

(bool registered, Subnet storage subnet) = LibGateway.getSubnet(subnetId);
Expand All @@ -58,18 +61,23 @@ contract GatewayManagerFacet is GatewayActorModifiers, ReentrancyGuard {
}

/// @notice addStake - add collateral for an existing subnet
function addStake() external payable {
if (msg.value == 0) {
function addStake(uint256 amount) external payable {
if (amount == 0) {
revert NotEnoughFunds();
}

// The fund flow for stake is from Validator -> SubnetActor -> Gateway.
// Because msg.sender is actually the subnet actor, this method sends the fund from
// the subnet actor caller the gateway.
SubnetActorGetterFacet(msg.sender).collateralSource().lock(amount);

(bool registered, Subnet storage subnet) = LibGateway.getSubnet(msg.sender);

if (!registered) {
revert NotRegisteredSubnet();
}

subnet.stake += msg.value;
subnet.stake += amount;
}

/// @notice release collateral for an existing subnet.
Expand All @@ -91,7 +99,10 @@ contract GatewayManagerFacet is GatewayActorModifiers, ReentrancyGuard {

subnet.stake -= amount;

payable(subnet.id.getActor()).sendValue(amount);
// Release fund flows from Gateway -> SubnetActor -> ReleaseQueue (Locking) -> Validator.
// Because msg.sender is actually the subnet actor, this method sends the fund back to
// the subnet actor caller.
SubnetActorGetterFacet(msg.sender).collateralSource().transferFunds(payable(msg.sender), amount);
}

/// @notice kill an existing subnet.
Expand All @@ -114,8 +125,7 @@ contract GatewayManagerFacet is GatewayActorModifiers, ReentrancyGuard {
delete s.subnets[id];

s.subnetKeys.remove(id);

payable(msg.sender).sendValue(stake);
SubnetActorGetterFacet(msg.sender).collateralSource().transferFunds(payable(msg.sender), stake);
}

/// @notice credits the received value to the specified address in the specified child subnet.
Expand All @@ -137,8 +147,8 @@ contract GatewayManagerFacet is GatewayActorModifiers, ReentrancyGuard {
}

// Validate that the supply strategy is native.
SupplySource memory supplySource = SubnetActorGetterFacet(subnetId.getActor()).supplySource();
supplySource.expect(SupplyKind.Native);
Asset memory supplySource = SubnetActorGetterFacet(subnetId.getActor()).supplySource();
supplySource.expect(AssetKind.Native);

IpcEnvelope memory crossMsg = CrossMsgHelper.createFundMsg({
subnet: subnetId,
Expand Down Expand Up @@ -172,8 +182,8 @@ contract GatewayManagerFacet is GatewayActorModifiers, ReentrancyGuard {
// Check that the supply strategy is ERC20.
// There is no need to check whether the subnet exists. If it doesn't exist, the call to getter will revert.
// LibGateway.commitTopDownMsg will also revert if the subnet doesn't exist.
SupplySource memory supplySource = SubnetActorGetterFacet(subnetId.getActor()).supplySource();
supplySource.expect(SupplyKind.ERC20);
Asset memory supplySource = SubnetActorGetterFacet(subnetId.getActor()).supplySource();
supplySource.expect(AssetKind.ERC20);

// Locks a specified amount into custody, adjusting for tokens with transfer fees. This operation
// accommodates inflationary tokens, potentially reflecting a higher effective locked amount.
Expand Down
4 changes: 2 additions & 2 deletions contracts/contracts/gateway/GatewayMessengerFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ pragma solidity ^0.8.23;
import {GatewayActorModifiers} from "../lib/LibGatewayActorStorage.sol";
import {IpcEnvelope, CallMsg, IpcMsgKind} from "../structs/CrossNet.sol";
import {IPCMsgType} from "../enums/IPCMsgType.sol";
import {SubnetID, SupplyKind, IPCAddress} from "../structs/Subnet.sol";
import {SubnetID, AssetKind, IPCAddress} from "../structs/Subnet.sol";
import {InvalidXnetMessage, InvalidXnetMessageReason, CannotSendCrossMsgToItself, MethodNotAllowed} from "../errors/IPCErrors.sol";
import {SubnetIDHelper} from "../lib/SubnetIDHelper.sol";
import {LibGateway} from "../lib/LibGateway.sol";
import {FilAddress} from "fevmate/contracts/utils/FilAddress.sol";
import {SupplySourceHelper} from "../lib/SupplySourceHelper.sol";
import {AssetHelper} from "../lib/AssetHelper.sol";
import {CrossMsgHelper} from "../lib/CrossMsgHelper.sol";
import {FvmAddressHelper} from "../lib/FvmAddressHelper.sol";

Expand Down
6 changes: 3 additions & 3 deletions contracts/contracts/gateway/router/XnetMessagingFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import {Subnet} from "../../structs/Subnet.sol";
import {FilAddress} from "fevmate/contracts/utils/FilAddress.sol";
import {SubnetIDHelper} from "../../lib/SubnetIDHelper.sol";
import {CrossMsgHelper} from "../../lib/CrossMsgHelper.sol";
import {SupplySourceHelper} from "../../lib/SupplySourceHelper.sol";
import {SupplySource} from "../../structs/Subnet.sol";
import {AssetHelper} from "../../lib/AssetHelper.sol";
import {Asset} from "../../structs/Subnet.sol";

import {NotRegisteredSubnet} from "../../errors/IPCErrors.sol";

contract XnetMessagingFacet is GatewayActorModifiers {
using SubnetIDHelper for SubnetID;
using CrossMsgHelper for IpcEnvelope;
using SupplySourceHelper for SupplySource;
using AssetHelper for Asset;

/// @notice Applies top-down cross-net messages locally. This is invoked by IPC nodes when drawing messages from
/// their parent subnet for local execution. That's why the sender is restricted to the system sender,
Expand Down
8 changes: 4 additions & 4 deletions contracts/contracts/interfaces/IGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import {FvmAddress} from "../structs/FvmAddress.sol";
interface IGateway {
/// @notice Register is called by subnet actors to put the required collateral
/// and register the subnet to the hierarchy.
function register(uint256 genesisCircSupply) external payable;
function register(uint256 genesisCircSupply, uint256 collateral) external payable;

/// @notice AddStake adds stake to the collateral of a subnet.
function addStake() external payable;
function addStake(uint256 amount) external payable;

/// @notice Release stake recovers some collateral of the subnet
function releaseStake(uint256 amount) external;
Expand All @@ -31,7 +31,7 @@ interface IGateway {
/// This functions ends up minting supply in the subnet equal to the value of the transaction. It does so by
/// committing the relevant top-down message, updating the top-down nonce along the way.
///
/// Calling this method on a subnet whose supply source is not 'native' will revert with UnexpectedSupplySource().
/// Calling this method on a subnet whose supply source is not 'native' will revert with UnexpectedAsset().
function fund(SubnetID calldata subnetId, FvmAddress calldata to) external payable;

/// @notice fundWithToken locks the specified amount of tokens in the ERC20 contract linked to the subnet, and
Expand All @@ -45,7 +45,7 @@ interface IGateway {
/// It's possible to call this method from an EOA or a contract. Regardless, it's recommended to approve strictly
/// the amount that will subsequently be deposited into the subnet. Keeping outstanding approvals is not recommended.
///
/// Calling this method on a subnet whose supply source is not 'ERC20' will revert with UnexpectedSupplySource().
/// Calling this method on a subnet whose supply source is not 'ERC20' will revert with UnexpectedAsset().
function fundWithToken(SubnetID calldata subnetId, FvmAddress calldata to, uint256 amount) external;

/// @notice Release creates a new check message to release funds in parent chain
Expand Down
Loading