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

Add TACo commitment checks and alerts when topping up or de-authing #724

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
11 changes: 9 additions & 2 deletions src/components/Modal/TopupTModal/TopUpTModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,15 @@ const TopupTModal: FC<
your initial stake.
</BodyLg>
<BodyLg>
If you want to put your new topped-up tokens at work, make sure to
increase the authorization to your applications.
If you want to put newly topped-up tokens to work, make sure to
individually increase the total authorization to each Threshold
application (tBTC, Random Beacon & TACo).
<br />
If you increase the total number of tokens authorized to the TACo
app, those tokens will automatically be subject to the same unlock
horizon as your current TACo stake, including the min.
deauthorization delay (6 months), plus any lock-up extension on
top of that.
</BodyLg>
</InfoBox>
<StakingStats
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { formatDate } from "../../../../utils/date"
import { calculatePercenteage } from "../../../../utils/percentage"
import { StakingAppForm } from "../../../../components/StakingApplicationForms"
import { AuthorizationStatus } from "../../../../types"
import { StakingProviderInfo } from "../../../../threshold-ts/applications"

interface CommonProps {
stakingAppId: StakingAppName
Expand All @@ -58,6 +59,7 @@ type StakingAppAuthDataBaseProps = {
remainingAuthorizationDecreaseDelay: string
isOperatorInPool: boolean | undefined
operator: string
stakingProviderInfo?: StakingProviderInfo | undefined
}

type AppAuthDataConditionalProps =
Expand Down Expand Up @@ -255,8 +257,28 @@ export const AuthorizeApplicationsCardCheckboxBase: FC<
}

const onSubmitForm = (tokenAmount: string) => {
if (isIncreaseAction) onAuthorizeApp(tokenAmount)
else onInitiateDeauthorization(tokenAmount)
if (isIncreaseAction) {
onAuthorizeApp(tokenAmount)
} else {
if (appAuthData.stakingAppId === "taco") {
// const endCommitment = appAuthData.stakingProviderInfo?.endCommitment
const endCommitment = appAuthData.stakingProviderInfo?.endCommitment
const currentTime = Math.floor(Date.now() / 1000)
const isCommited = (Number(endCommitment) ?? 0) > currentTime
const endCommitmentDate = new Date(
(Number(endCommitment) ?? 0) * 1000
).toLocaleDateString()
if (isCommited) {
alert(
`Your tokens remain committed until ${endCommitmentDate}, at which point you may initiate deauthorization.`
)
} else {
onInitiateDeauthorization(tokenAmount)
}
} else {
onInitiateDeauthorization(tokenAmount)
}
}
}

const onConfirmDeauthorization = () => {
Expand Down
10 changes: 9 additions & 1 deletion src/pages/Staking/StakeDetailsPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ const StakeDetailsPage: FC = () => {
stakingProviderAddress || AddressZero
)

const endCommitment = tacoApp.stakingProviderInfo?.endCommitment
const isCommited = (Number(endCommitment) ?? 0) > 0
const endCommitmentDate = new Date(
(Number(endCommitment) ?? 0) * 1000
).toLocaleDateString()

const isInActiveStake = BigNumber.from(stake?.totalInTStake ?? "0").isZero()

const { total: rewardsForStake } = useAppSelector((state) =>
Expand Down Expand Up @@ -166,10 +172,12 @@ const StakeDetailsPage: FC = () => {
</StakeDetailRow>
</Stack>
</SimpleGrid>
{tacoApp.isAuthorized && (
{tacoApp.isAuthorized && !isCommited ? (
<Button onClick={handleCommitToTaco} type="submit">
Commit to TACo
</Button>
) : (
<p>Your commitment ends on {endCommitmentDate}</p>
)}
</Card>
) : (
Expand Down
1 change: 1 addition & 0 deletions src/store/staking-applications/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ export const stakingApplicationsSlice = createSlice({
deauthorizationCreatedAt: undefined,
isOperatorInPool: undefined,
operator: AddressZero,
stakingProviderInfo: undefined,
}

state.randomBeacon.stakingProviders.data[stakingProvider] = {
Expand Down
42 changes: 42 additions & 0 deletions src/threshold-ts/applications/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ export interface AuthorizationParameters<
authorizationDecreaseChangePeriod: NumberType
}

export interface StakingProviderInfo<
NumberType extends BigNumberish = BigNumber
> {
operator: string
operatorConfirmed: boolean
operatorStartTimestamp: NumberType
authorized: NumberType
deauthorizing: NumberType
endDeauthorization: NumberType
tReward: NumberType
rewardPerTokenPaid: NumberType
endCommitment: NumberType
}

export interface StakingProviderAppInfo<
NumberType extends BigNumberish = BigNumber
> {
Expand Down Expand Up @@ -75,6 +89,8 @@ export interface StakingProviderAppInfo<
* it means that the operator for a given staking provider is not set.
*/
isOperatorInPool: boolean | undefined

stakingProviderInfo?: StakingProviderInfo | undefined
}

/**
Expand Down Expand Up @@ -202,6 +218,8 @@ export interface IApplication {
*/
stakingProviderToOperator(stakingProvider: string): Promise<string>

stakingProviderInfo(stakingProvider: string): Promise<StakingProviderInfo>

/**
* Used to get staking provider address mapped to the given registered
* operator address
Expand Down Expand Up @@ -314,6 +332,15 @@ export class Application implements IApplication {
},
]

const tacoCalls: ContractCall[] = [
{
interface: this.contract.interface,
address: this.contract.address,
method: "stakingProviderInfo",
args: [stakingProvider],
},
]

const [
authorizedStake,
pendingAuthorizationDecrease,
Expand All @@ -323,6 +350,14 @@ export class Application implements IApplication {
[operator],
] = await this._multicall.aggregate(calls)

let stakingProviderInfo
try {
;[stakingProviderInfo] = await this._multicall.aggregate(tacoCalls)
} catch (error) {
console.warn("Failed to aggregate tacoCalls", error)
stakingProviderInfo = undefined
}

let isOperatorInPool = undefined
if (operator && !isAddressZero(operator)) {
try {
Expand Down Expand Up @@ -368,6 +403,7 @@ export class Application implements IApplication {
deauthorizationCreatedAt,
isOperatorInPool,
operator,
stakingProviderInfo,
}
}

Expand Down Expand Up @@ -448,6 +484,12 @@ export class Application implements IApplication {
)
}

stakingProviderInfo = async (
stakingProvider: string
): Promise<StakingProviderInfo> => {
return await this._application.stakingProviderInfo(stakingProvider)
}

stakingProviderToOperator = async (
stakingProvider: string
): Promise<string> => {
Expand Down
Loading