Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
hellwolf committed Mar 8, 2024
1 parent 7edc0fb commit ad75968
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { SafeGasLibrary } from "../../libs/SafeGasLibrary.sol";
import { AgreementBase } from "../AgreementBase.sol";
import { AgreementLibrary } from "../AgreementLibrary.sol";


/**
* @title General Distribution Agreement
* @author Superfluid
Expand Down Expand Up @@ -80,6 +81,25 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
using SafeCast for int256;
using SemanticMoney for BasicParticle;

struct UniversalIndexData {
int96 flowRate;
uint32 settledAt;
uint256 totalBuffer;
bool isPool;
int256 settledValue;
}

struct PoolMemberData {
address pool;
uint32 poolID; // the slot id in the pool's subs bitmap
}

struct FlowDistributionData {
uint32 lastUpdated;
int96 flowRate;
uint256 buffer; // stored as uint96
}

address public constant SLOTS_BITMAP_LIBRARY_ADDRESS = address(SlotsBitmapLibrary);

address public constant SUPERFLUID_POOL_DEPLOYER_ADDRESS = address(SuperfluidPoolDeployerLibrary);
Expand Down Expand Up @@ -170,6 +190,18 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
return data.flowRate;
}

function getFlow(ISuperfluidToken token, address from, ISuperfluidPool to)
external
view
override
returns (uint256 lastUpdated, int96 flowRate, uint256 deposit)
{
(, FlowDistributionData memory data) = _getFlowDistributionData(token, _getFlowDistributionHash(from, to));
lastUpdated = data.lastUpdated;
flowRate = data.flowRate;
deposit = data.buffer;
}

/// @inheritdoc IGeneralDistributionAgreementV1
function estimateFlowDistributionActualFlowRate(
ISuperfluidToken token,
Expand Down Expand Up @@ -428,6 +460,15 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
FlowRate oldFlowRate;
}

struct _StackVars_Liquidation {
ISuperfluidToken token;
int256 availableBalance;
address sender;
bytes32 distributionFlowHash;
int256 signedTotalGDADeposit;
address liquidator;
}

/// @inheritdoc IGeneralDistributionAgreementV1
function distributeFlow(
ISuperfluidToken token,
Expand Down Expand Up @@ -482,7 +523,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
// liquidation case, requestedFlowRate == 0
(int256 availableBalance,,) = token.realtimeBalanceOf(from, flowVars.currentContext.timestamp);
// StackVarsLiquidation used to handle good ol' stack too deep
StackVarsLiquidation memory liquidationData;
_StackVars_Liquidation memory liquidationData;
{
liquidationData.token = token;
liquidationData.sender = from;
Expand Down Expand Up @@ -612,7 +653,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
}
}

function _makeLiquidationPayouts(StackVarsLiquidation memory data) internal {
function _makeLiquidationPayouts(_StackVars_Liquidation memory data) internal {
(, FlowDistributionData memory flowDistributionData) =
_getFlowDistributionData(ISuperfluidToken(data.token), data.distributionFlowHash);
int256 signedSingleDeposit = flowDistributionData.buffer.toInt256();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {
using SafeCast for uint256;
using SafeCast for int256;

// Structs
struct PoolIndexData {
uint128 totalUnits;
uint32 wrappedSettledAt;
int96 wrappedFlowRate;
int256 wrappedSettledValue;
}

struct MemberData {
uint128 ownedUnits;
uint32 syncedSettledAt;
int96 syncedFlowRate;
int256 syncedSettledValue;
int256 settledValue;
int256 claimedValue;
}

GeneralDistributionAgreementV1 public immutable GDA;

ISuperfluidToken public superToken;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,10 @@ library SuperTokenV1Library {
(lastUpdated, flowRate, deposit, owedDeposit) = cfa.getFlow(token, sender, receiver);
}

/* function getGDAFlowInfo(ISuperToken token, address distributor, ISuperfluidPool pool) */
/* { */
/* } */

/**
* @dev get net flow rate for given account for given token (CFA + GDA)
* @param token Super token address
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,6 @@ struct PoolConfig {
* @author Superfluid
*/
abstract contract IGeneralDistributionAgreementV1 is ISuperAgreement {
// Structs
struct UniversalIndexData {
int96 flowRate;
uint32 settledAt;
uint256 totalBuffer;
bool isPool;
int256 settledValue;
}

struct FlowDistributionData {
uint32 lastUpdated;
int96 flowRate;
uint256 buffer; // stored as uint96
}

struct PoolMemberData {
address pool;
uint32 poolID; // the slot id in the pool's subs bitmap
}

struct StackVarsLiquidation {
ISuperfluidToken token;
int256 availableBalance;
address sender;
bytes32 distributionFlowHash;
int256 signedTotalGDADeposit;
address liquidator;
}


// Custom Errors
error GDA_DISTRIBUTE_FOR_OTHERS_NOT_ALLOWED(); // 0xf67d263e
Expand Down Expand Up @@ -131,6 +102,18 @@ abstract contract IGeneralDistributionAgreementV1 is ISuperAgreement {
virtual
returns (int96);

function getFlow(ISuperfluidToken token, address from, ISuperfluidPool to)
external
view
virtual
returns (uint256 lastUpdated, int96 flowRate, uint256 deposit);

function getAccountFlow(ISuperfluidPool token, address account)
external
view
virtual
returns (uint256 timestamp, int96 flowRate, uint256 deposit);

/// @notice Executes an optimistic estimation of what the actual flow distribution flow rate may be.
/// The actual flow distribution flow rate is the flow rate that will be sent from `from`.
/// NOTE: this is only precise in an atomic transaction. DO NOT rely on this if querying off-chain.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import { SuperfluidUpgradeableBeacon } from "../../../../contracts/upgradability
import { ISuperToken, SuperToken } from "../../../../contracts/superfluid/SuperToken.sol";
import { ISuperAgreement } from "../../../../contracts/interfaces/superfluid/ISuperAgreement.sol";
import {
GeneralDistributionAgreementV1,
ISuperfluid,
ISuperfluidPool
GeneralDistributionAgreementV1, ISuperfluid, ISuperfluidPool
} from "../../../../contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol";
import {
IGeneralDistributionAgreementV1,
Expand Down Expand Up @@ -124,7 +122,7 @@ contract GeneralDistributionAgreementV1Properties is GeneralDistributionAgreemen

vm.warp(1000);

(bool exist, IGeneralDistributionAgreementV1.FlowDistributionData memory setFlowDistributionData) =
(bool exist, FlowDistributionData memory setFlowDistributionData) =
_getFlowDistributionData(superToken, flowHash);

assertEq(true, exist, "flow distribution data does not exist");
Expand Down Expand Up @@ -156,14 +154,11 @@ contract GeneralDistributionAgreementV1Properties is GeneralDistributionAgreemen
vm.startPrank(address(this));
superToken.updateAgreementData(
poolMemberId,
_encodePoolMemberData(
IGeneralDistributionAgreementV1.PoolMemberData({ poolID: poolID, pool: address(_pool) })
)
_encodePoolMemberData(PoolMemberData({ poolID: poolID, pool: address(_pool) }))
);
vm.stopPrank();

(bool exist, IGeneralDistributionAgreementV1.PoolMemberData memory setPoolMemberData) =
_getPoolMemberData(superToken, poolMember, _pool);
(bool exist, PoolMemberData memory setPoolMemberData) = _getPoolMemberData(superToken, poolMember, _pool);

assertEq(true, exist, "pool member data does not exist");
assertEq(poolID, setPoolMemberData.poolID, "poolID not equal");
Expand Down Expand Up @@ -333,11 +328,10 @@ contract GeneralDistributionAgreementV1Properties is GeneralDistributionAgreemen
function testEncodeDecodeFlowDistributionData(int96 flowRate, uint96 buffer) public {
vm.assume(flowRate >= 0);
vm.assume(buffer >= 0);
IGeneralDistributionAgreementV1.FlowDistributionData memory original = IGeneralDistributionAgreementV1
.FlowDistributionData({ flowRate: flowRate, lastUpdated: uint32(block.timestamp), buffer: buffer });
FlowDistributionData memory original =
FlowDistributionData({ flowRate: flowRate, lastUpdated: uint32(block.timestamp), buffer: buffer });
bytes32[] memory encoded = _encodeFlowDistributionData(original);
(, IGeneralDistributionAgreementV1.FlowDistributionData memory decoded) =
_decodeFlowDistributionData(uint256(encoded[0]));
(, FlowDistributionData memory decoded) = _decodeFlowDistributionData(uint256(encoded[0]));

assertEq(original.flowRate, decoded.flowRate, "flowRate not equal");
assertEq(original.buffer, decoded.buffer, "buffer not equal");
Expand All @@ -346,10 +340,9 @@ contract GeneralDistributionAgreementV1Properties is GeneralDistributionAgreemen

function testEncodeDecodePoolMemberData(address pool, uint32 poolID) public {
vm.assume(pool != address(0));
IGeneralDistributionAgreementV1.PoolMemberData memory original =
IGeneralDistributionAgreementV1.PoolMemberData({ pool: pool, poolID: poolID });
PoolMemberData memory original = PoolMemberData({ pool: pool, poolID: poolID });
bytes32[] memory encoded = _encodePoolMemberData(original);
(, IGeneralDistributionAgreementV1.PoolMemberData memory decoded) = _decodePoolMemberData(uint256(encoded[0]));
(, PoolMemberData memory decoded) = _decodePoolMemberData(uint256(encoded[0]));

assertEq(original.pool, decoded.pool, "pool not equal");
assertEq(original.poolID, decoded.poolID, "poolID not equal");
Expand Down

0 comments on commit ad75968

Please sign in to comment.