Skip to content

Commit

Permalink
feat(sdk): ManagedBudgetWithFees sdk impl
Browse files Browse the repository at this point in the history
This changeset implements the functionality needed to interact with
ManagedBudgetWithFees from the sdk. In the core constructor I've also
added the core address to the authorized list to minimize the chances of
a footgun where BoostCore is not configured correctly in the budget.
  • Loading branch information
topocount committed Nov 25, 2024
1 parent 03e9f51 commit bcdaf13
Show file tree
Hide file tree
Showing 10 changed files with 1,130 additions and 17 deletions.
7 changes: 7 additions & 0 deletions .changeset/famous-chefs-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@boostxyz/cli": minor
"@boostxyz/evm": minor
"@boostxyz/sdk": minor
---

Add ManagedBudgetWithFees
15 changes: 15 additions & 0 deletions packages/cli/src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import EventActionArtifact from '@boostxyz/evm/artifacts/contracts/actions/Event
import SimpleAllowListArtifact from '@boostxyz/evm/artifacts/contracts/allowlists/SimpleAllowList.sol/SimpleAllowList.json';
import SimpleDenyListArtifact from '@boostxyz/evm/artifacts/contracts/allowlists/SimpleDenyList.sol/SimpleDenyList.json';
import ManagedBudgetArtifact from '@boostxyz/evm/artifacts/contracts/budgets/ManagedBudget.sol/ManagedBudget.json';
import ManagedBudgetWithFeesArtifact from '@boostxyz/evm/artifacts/contracts/budgets/ManagedBudgetWithFees.sol/ManagedBudgetWithFees.json';
import VestingBudgetArtifact from '@boostxyz/evm/artifacts/contracts/budgets/VestingBudget.sol/VestingBudget.json';
import AllowListIncentiveArtifact from '@boostxyz/evm/artifacts/contracts/incentives/AllowListIncentive.sol/AllowListIncentive.json';
import CGDAIncentiveArtifact from '@boostxyz/evm/artifacts/contracts/incentives/CGDAIncentive.sol/CGDAIncentive.json';
Expand All @@ -26,6 +27,7 @@ import {
EventAction,
LimitedSignerValidator,
ManagedBudget,
ManagedBudgetWithFees,
PointsIncentive,
SignerValidator,
SimpleAllowList,
Expand Down Expand Up @@ -162,6 +164,14 @@ export const deploy: Command<DeployResult> = async function deploy(
account,
}),
);
const managedBudgetWithFeesBase = await getDeployedContractAddress(
config,
deployContract(config, {
abi: ManagedBudgetWithFeesArtifact.abi,
bytecode: ManagedBudgetWithFeesArtifact.bytecode as Hex,
account,
}),
);
const vestingBudgetBase = await getDeployedContractAddress(
config,
deployContract(config, {
Expand Down Expand Up @@ -287,6 +297,11 @@ export const deploy: Command<DeployResult> = async function deploy(
[chainId]: managedBudgetBase,
} as Record<number, Address>;
},
ManagedBudgetWithFees: class TManagedBudgetWithFees extends ManagedBudgetWithFees {
public static override bases: Record<number, Address> = {
[chainId]: managedBudgetWithFeesBase,
} as Record<number, Address>;
},
// VestingBudget: class TVestingBudget extends VestingBudget {
// public static override base = vestingBudgetBase;
// },
Expand Down
7 changes: 7 additions & 0 deletions packages/evm/script/solidity/ComponentInterface.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {ACloneable} from "contracts/shared/ACloneable.sol";

import {ABudget} from "contracts/budgets/ABudget.sol";
import {AManagedBudget} from "contracts/budgets/AManagedBudget.sol";
import {AManagedBudgetWithFees} from "contracts/budgets/AManagedBudgetWithFees.sol";
import {AVestingBudget} from "contracts/budgets/AVestingBudget.sol";

import {ASignerValidator} from "contracts/validators/ASignerValidator.sol";
Expand Down Expand Up @@ -39,6 +40,7 @@ contract LogComponentInterface is ScriptUtils {
_getInterfaceACloneable();
_getInterfaceABudget();
_getInterfaceAManagedBudget();
_getInterfaceAManagedBudgetWithFees();
_getInterfaceAVestingBudget();
_getInterfaceASignerValidator();
_getInterfaceAAllowListIncentive();
Expand Down Expand Up @@ -66,6 +68,11 @@ contract LogComponentInterface is ScriptUtils {
componentJson = componentJsonKey.serialize("AManagedBudget", interfaceId);
}

function _getInterfaceAManagedBudgetWithFees() internal {
string memory interfaceId = uint256(uint32(type(AManagedBudgetWithFees).interfaceId)).toHexString(4);
componentJson = componentJsonKey.serialize("AManagedBudgetWithFees", interfaceId);
}

function _getInterfaceAEventAction() internal {
string memory interfaceId = uint256(uint32(type(AEventAction).interfaceId)).toHexString(4);
componentJson = componentJsonKey.serialize("AEventAction", interfaceId);
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/.env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ VITE_SIMPLE_ALLOWLIST_BASE=
VITE_SIMPLE_DENYLIST_BASE=
VITE_VESTING_BUDGET_BASE=
VITE_MANAGED_BUDGET_BASE=
VITE_MANAGED_BUDGET_WITH_FEES_BASE=
VITE_ALLOWLIST_INCENTIVE_BASE=
VITE_CGDA_INCENTIVE_BASE=
VITE_ERC20_INCENTIVE_BASE=
Expand Down
30 changes: 30 additions & 0 deletions packages/sdk/src/BoostCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,17 @@ import {
ManagedBudget,
type ManagedBudgetPayload,
} from './Budgets/ManagedBudget';
import {
ManagedBudgetWithFees,
type ManagedBudgetWithFeesPayload,
} from './Budgets/ManagedBudgetWithFees';
import {
Deployable,
type DeployableOptions,
type DeployablePayloadOrAddress,
type GenericDeployableParams,
} from './Deployable/Deployable';
import { Roles } from './Deployable/DeployableTargetWithRBAC';
import {
AllowListIncentive,
type AllowListIncentivePayload,
Expand Down Expand Up @@ -1268,6 +1273,31 @@ export class BoostCore extends Deployable<
options,
);
}
/**
* Bound {@link ManagedBudgetWithFees} constructor that reuses the same configuration as the Boost Core instance.
* Prepends the BoostCore address to the authorized list because it's structurally critical to calculating payouts.
*
* @example
* ```ts
* const budget = core.ManagedBudgetWithFees('0x') // is roughly equivalent to
* const budget = new ManagedBudgetWithFees({ config: core._config, account: core._account }, '0x')
* ```
* @param {DeployablePayloadOrAddress<ManagedBudgetWithFeesPayload>} options
* @returns {ManagedBudgetWithFees}
*/
ManagedBudgetWithFees(
options: DeployablePayloadOrAddress<ManagedBudgetWithFeesPayload>,
) {
if (typeof options !== 'string') {
options.authorized = [this.assertValidAddress(), ...options.authorized];
options.roles = [Roles.MANAGER, ...options.roles];
}

return new ManagedBudgetWithFees(
{ config: this._config, account: this._account },
options,
);
}
// /**
// * Bound {@link VestingBudget} constructor that reuses the same configuration as the Boost Core instance.
// *
Expand Down
11 changes: 8 additions & 3 deletions packages/sdk/src/Budgets/Budget.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { aBudgetAbi } from '@boostxyz/evm';
import { AManagedBudget } from '@boostxyz/evm/deploys/componentInterfaces.json';
import {
AManagedBudget,
AManagedBudgetWithFees,
} from '@boostxyz/evm/deploys/componentInterfaces.json';
import { readContract } from '@wagmi/core';
import type { Address, Hex } from 'viem';
import type { DeployableOptions } from '../Deployable/Deployable';
import { InvalidComponentInterfaceError } from '../errors';
import { ManagedBudget } from './ManagedBudget';
import { ManagedBudgetWithFees } from './ManagedBudgetWithFees';

export {
// VestingBudget,
Expand All @@ -17,7 +21,7 @@ export {
* @export
* @typedef {Budget}
*/
export type Budget = ManagedBudget; // | VestingBudget
export type Budget = ManagedBudget | ManagedBudgetWithFees; // | VestingBudget

/**
* A map of Budget component interfaces to their constructors.
Expand All @@ -28,6 +32,7 @@ export const BudgetByComponentInterface = {
// ['0x64683da1']: VestingBudget,
// ['0x2929d19c']: SimpleBudget,
[AManagedBudget as Hex]: ManagedBudget,
[AManagedBudgetWithFees as Hex]: ManagedBudgetWithFees,
};

/**
Expand All @@ -37,7 +42,7 @@ export const BudgetByComponentInterface = {
* @async
* @param {DeployableOptions} options
* @param {Address} address
* @returns {Promise<ManagedBudget>}
* @returns {Promise<ManagedBudget | ManagedBudgetWithFees>}
* @throws {@link InvalidComponentInterfaceError}
*/
export async function budgetFromAddress(
Expand Down
Loading

0 comments on commit bcdaf13

Please sign in to comment.