Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎛️ Integrate the crt constraints proposal #4822

Merged
merged 13 commits into from
Apr 8, 2024
12,405 changes: 12,051 additions & 354 deletions .yarn/patches/@joystream-types-npm-4.3.0-542438a0b6.patch

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions packages/server/src/common/queries/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2592,6 +2592,7 @@ union ProposalDetails =
| UpdatePalletFrozenStatusProposalDetails
| UpdateGlobalNftLimitProposalDetails
| DecreaseCouncilBudgetProposalDetails
| UpdateTokenPalletTokenConstraintsProposalDetails

union ProposalStatus =
ProposalStatusDeciding
Expand Down Expand Up @@ -3562,6 +3563,53 @@ type UpdatePalletFrozenStatusProposalDetails {
pallet: String!
}

type UpdateTokenPalletTokenConstraintsProposalDetails {
"""
Proposed maximum patronage yearly interest rate (in part per million)
"""
maxYearlyRate: Int

"""
Proposed minimum value of the slope amm parameter
"""
minAmmSlope: BigInt

"""
Proposed minimum block duration of sales
"""
minSaleDuration: Int

"""
Proposed minimum block duration for a revenue split
"""
minRevenueSplitDuration: Int

"""
Proposed minimum blocks between revenue share issuance block and actual revenue share starting block
"""
minRevenueSplitTimeToStart: Int

"""
Proposed platform fee ratio charged on top of each sale and burned (in part per million)
"""
salePlatformFee: Int

"""
Proposed ratio of fees charged on top of each token purchase from the AMM (in part per million)
"""
ammBuyTxFees: Int

"""
Proposed ratio of fees charged on top of each token sold to the AMM (in part per million)
"""
ammSellTxFees: Int

"""
Proposed bloat bond value used during account creation
"""
bloatBond: BigInt
}

type UpdateWorkingGroupBudgetProposalDetails {
"""
Amount to increase / decrease the working group budget by (will be decudted from / appended to council budget accordingly)
Expand Down
73 changes: 73 additions & 0 deletions packages/ui/src/app/pages/Proposals/CurrentProposals.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ export default {
},
projectToken: {
palletFrozen: args.palletFrozen,

ammBuyTxFees: 10_000,
ammSellTxFees: 20_000,
bloatBond: joy(0.1),
maxYearlyPatronageRate: 500_000,
minAmmSlopeParameter: joy(10),
minRevenueSplitDuration: 100,
minRevenueSplitTimeToStart: 200,
minSaleDuration: 300,
salePlatformFee: 30_000,
},
},
tx: {
Expand Down Expand Up @@ -1577,3 +1587,66 @@ export const SpecificParametersDecreaseCouncilBudget: Story = {
})
}),
}

export const SpecificUpdateTokenPalletTokenConstraints: Story = {
play: specificParametersTest(
'Update Token Pallet Token Constraints',
async ({ args, createProposal, modal, step }) => {
await createProposal(async () => {
const nextButton = getButtonByText(modal, 'Create proposal')
expect(nextButton).toBeDisabled()

const maxYearlyRate = await modal.findByLabelText('Maximum yearly rate')
const minAmmSlope = await modal.findByLabelText('Minimum AMM slope')
const minSaleDuration = await modal.findByLabelText('Minimum sale duration')
const minRevenueSplitDuration = await modal.findByLabelText('Minimum revenue split duration')
const minRevenueSplitTimeToStart = await modal.findByLabelText('Minimum revenue split time to start')
const salePlatformFee = await modal.findByLabelText('Sale platform fee')
const ammBuyTxFees = await modal.findByLabelText('AMM buy transaction fees')
const ammSellTxFees = await modal.findByLabelText('AMM sell transaction fees')
const bloatBond = await modal.findByLabelText('Bloat bond')

// Valid
await userEvent.type(maxYearlyRate, '40')
await waitFor(() => expect(nextButton).toBeEnabled())

// Invalid min AMM slope
await userEvent.type(minAmmSlope, '0')
await waitFor(() => expect(nextButton).toBeDisabled())

// Invalid Bloat bond
await userEvent.clear(minAmmSlope)
await userEvent.type(minAmmSlope, '1')
await waitFor(() => expect(nextButton).toBeEnabled())
await userEvent.type(bloatBond, '0')
await waitFor(() => expect(nextButton).toBeDisabled())

// Valid again
await userEvent.clear(bloatBond)
await userEvent.type(bloatBond, '0.01')
await userEvent.type(minSaleDuration, '100')
await userEvent.type(minRevenueSplitDuration, '200')
await userEvent.type(minRevenueSplitTimeToStart, '300')
await userEvent.type(salePlatformFee, '0.1')
await userEvent.type(ammBuyTxFees, '0.2')
await userEvent.type(ammSellTxFees, '0.3')
await waitFor(() => expect(nextButton).toBeEnabled())
})

await step('Transaction parameters', () => {
const [, , specificParameters] = args.onCreateProposal.mock.calls.at(-1)
expect(specificParameters.toJSON().updateTokenPalletTokenConstraints).toEqual({
maxYearlyRate: 0.4 * 1_000_000,
minAmmSlope: Number(joy(1)),
minSaleDuration: 100,
minRevenueSplitDuration: 200,
minRevenueSplitTimeToStart: 300,
salePlatformFee: 0.001 * 1_000_000,
ammBuyTxFees: 0.002 * 1_000_000,
ammSellTxFees: 0.003 * 1_000_000,
bloatBond: Number(joy(0.01)),
})
})
}
),
}
14 changes: 14 additions & 0 deletions packages/ui/src/app/pages/Proposals/ProposalPreview.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ export default {
councilorReward: joy(1),
},
referendum: { stage: {} },
projectToken: {
ammBuyTxFees: 10_000,
ammSellTxFees: 20_000,
bloatBond: joy(0.1),
maxYearlyPatronageRate: 500_000,
minAmmSlopeParameter: joy(10),
minRevenueSplitDuration: 100,
minRevenueSplitTimeToStart: 200,
minSaleDuration: 300,
salePlatformFee: 30_000,
},
},

tx: {
Expand Down Expand Up @@ -299,6 +310,9 @@ export const UpdateWorkingGroupBudget: Story = {
export const DecreaseCouncilBudget: Story = {
args: { type: 'DecreaseCouncilBudgetProposalDetails' },
}
export const UpdateTokenPalletTokenConstraints: Story = {
args: { type: 'UpdateTokenPalletTokenConstraintsProposalDetails' },
}

// Disabled proposals
export const Veto: Story = {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions packages/ui/src/common/api/schemas/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2592,6 +2592,7 @@ union ProposalDetails =
| UpdatePalletFrozenStatusProposalDetails
| UpdateGlobalNftLimitProposalDetails
| DecreaseCouncilBudgetProposalDetails
| UpdateTokenPalletTokenConstraintsProposalDetails

union ProposalStatus =
ProposalStatusDeciding
Expand Down Expand Up @@ -3562,6 +3563,53 @@ type UpdatePalletFrozenStatusProposalDetails {
pallet: String!
}

type UpdateTokenPalletTokenConstraintsProposalDetails {
"""
Proposed maximum patronage yearly interest rate (in part per million)
"""
maxYearlyRate: Int

"""
Proposed minimum value of the slope amm parameter
"""
minAmmSlope: BigInt

"""
Proposed minimum block duration of sales
"""
minSaleDuration: Int

"""
Proposed minimum block duration for a revenue split
"""
minRevenueSplitDuration: Int

"""
Proposed minimum blocks between revenue share issuance block and actual revenue share starting block
"""
minRevenueSplitTimeToStart: Int

"""
Proposed platform fee ratio charged on top of each sale and burned (in part per million)
"""
salePlatformFee: Int

"""
Proposed ratio of fees charged on top of each token purchase from the AMM (in part per million)
"""
ammBuyTxFees: Int

"""
Proposed ratio of fees charged on top of each token sold to the AMM (in part per million)
"""
ammSellTxFees: Int

"""
Proposed bloat bond value used during account creation
"""
bloatBond: BigInt
}

type UpdateWorkingGroupBudgetProposalDetails {
"""
Amount to increase / decrease the working group budget by (will be decudted from / appended to council budget accordingly)
Expand Down
20 changes: 3 additions & 17 deletions packages/ui/src/common/components/forms/InputComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ export const InputComponent = React.memo(
</InputLabel>
)}
{sublabel && (
<InputSublabelWrapper>
<InputSublabel>{sublabel}</InputSublabel>
</InputSublabelWrapper>
<label htmlFor={id}>
<TextSmall light>{sublabel}</TextSmall>
</label>
)}
<InputContainer
copy={copy}
Expand Down Expand Up @@ -267,20 +267,6 @@ const InputLabel = styled(Label)<DisabledInputProps>`
color: ${({ disabled }) => (disabled ? Colors.Black[500] : Colors.Black[900])};
`

const InputSublabelWrapper = styled.div`
position: relative;
height: 20px;
margin-bottom: 16px;
`

const InputSublabel = styled(Label)`
font-weight: 400;
font-family: ${Fonts.Inter};
color: ${Colors.Black[700]};
position: absolute;
white-space: nowrap;
`

export const InputIcon = styled.div<DisabledInputProps>`
display: flex;
position: absolute;
Expand Down
57 changes: 57 additions & 0 deletions packages/ui/src/common/components/forms/InputNumber.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Meta, StoryObj } from '@storybook/react'
import React, { FC, useEffect } from 'react'
import { useFormContext } from 'react-hook-form'

import { InputComponent } from './InputComponent'
import { InputNumber } from './InputNumber'

type Args = {
maxAllowedValue: number
placeholder: string
label: string
units: string
decimalScale: number
onChange: (value: number) => void
}
type Story = StoryObj<FC<Args>>

export default {
title: 'Common/Forms/InputNumber',
component: InputNumber as unknown as FC<Args>,

argTypes: {
onChange: { action: 'onChange' },
},

args: {
maxAllowedValue: 10_000,
placeholder: '0',
label: 'Amount',
units: 'per 10 000',
decimalScale: 2,
},
} satisfies Meta<Args>

export const InputNumberStory: Story = {
name: 'InputNumber',
render: ({ label, units, onChange, ...props }) => {
const form = useFormContext()

useEffect(() => {
const subscription = form.watch((data) => onChange(data.input))
return () => subscription.unsubscribe()
}, [form.watch])

return (
<InputComponent
id="input"
label={label}
units={units}
message={`Value must be between 0 and ${props.maxAllowedValue}.`}
tight
>
<InputNumber {...props} id="input" name="input" />
</InputComponent>
)
},
}
Loading
Loading