Skip to content

Commit

Permalink
feat(migration): use forwarder for staking
Browse files Browse the repository at this point in the history
  • Loading branch information
envin3 committed Mar 8, 2024
1 parent 3e6c7dc commit 7a51768
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/components/complex/MigrateModal/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ const MigrateModal = () => {
stakeData,
stakeEnabled,
stakeError
} = useStake()
} = useStake({ migration: true })

const onShowOrHideAdvancedOptions = useCallback(() => {
setShowAdvancedOptions(!showAdvancedOptions)
Expand Down
108 changes: 87 additions & 21 deletions src/hooks/use-staking-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,32 @@ import StakingManagerABI from '../utils/abis/StakingManager.json'
import { formatAssetAmount } from '../utils/amount'
import { SECONDS_IN_ONE_DAY } from '../utils/time'

const useStake = () => {
const subtractFee = (_amount) => {
const amountBn = BigNumber(_amount.toString())
return amountBn.minus(amountBn.multipliedBy(0.001)).toFixed()
}

const getForwarderStakeUserData = ({ amount, duration, receiverAddress }) => {
const erc20Interface = new ethers.utils.Interface(['function approve(address spender, uint256 amount)'])
const stakingManagerInterface = new ethers.utils.Interface([
'function stake(address receiver, uint256 amount, uint64 duration)'
])

const amountWithoutFees = subtractFee(amount)

return encode(
['address[]', 'bytes[]'],
[
[settings.contracts.pntOnGnosis, settings.contracts.stakingManager],
[
erc20Interface.encodeFunctionData('approve', [settings.contracts.stakingManager, amountWithoutFees]),
stakingManagerInterface.encodeFunctionData('stake', [receiverAddress, amountWithoutFees, duration])
]
]
)
}

const useStake = ({ migration = false }) => {
const [approved, setApproved] = useState(false)
const [receiver, setReceiver] = useState('')
const [amount, setAmount] = useState('0')
Expand All @@ -30,26 +55,44 @@ const useStake = () => {
address
})

const { data: allowance } = useContractRead({
address: settings.contracts.pnt,
abi: erc20ABI,
functionName: 'allowance',
args: [address, settings.contracts.stakingManager]
})
const getAllowanceData = migration
? {
address: settings.contracts.pnt,
abi: erc20ABI,
functionName: 'allowance',
args: [address, settings.contracts.forwarderOnMainnet]
}
: {
address: settings.contracts.pnt,
abi: erc20ABI,
functionName: 'allowance',
args: [address, settings.contracts.stakingManager]
}

const { data: allowance } = useContractRead(getAllowanceData)

const onChainAmount = useMemo(
() => (amount.length > 0 ? ethers.utils.parseEther(amount) : ethers.BigNumber.from('0')),
[amount]
)

const approveEnabled = useMemo(() => onChainAmount.gt(0) && !approved, [onChainAmount, approved])
const { config: approveConfigs } = usePrepareContractWrite({
address: settings.contracts.pnt,
abi: erc20ABI,
functionName: 'approve',
args: [settings.contracts.stakingManager, onChainAmount],
enabled: approveEnabled
})
const getApproveData = migration
? {
address: settings.contracts.pntOnEthereum,
abi: erc20ABI,
functionName: 'approve',
args: [settings.contracts.forwarderOnMainnet, amount],
enabled: approveEnabled
}
: {
address: settings.contracts.pnt,
abi: erc20ABI,
functionName: 'approve',
args: [settings.contracts.stakingManager, onChainAmount],
enabled: approveEnabled
}
const { config: approveConfigs } = usePrepareContractWrite(getApproveData)
const { write: approve, error: approveError, data: approveData } = useContractWrite(approveConfigs)

const stakeEnabled = useMemo(
Expand All @@ -60,13 +103,36 @@ const useStake = () => {
duration >= settings.stakingManager.minStakeDays,
[onChainAmount, approved, pntBalanceData, duration]
)
const { config: stakeConfigs } = usePrepareContractWrite({
address: settings.contracts.stakingManager,
abi: StakingManagerABI,
functionName: 'stake',
args: [onChainAmount, duration * SECONDS_IN_ONE_DAY, receiver],
enabled: stakeEnabled
})

const migrationPrepareData = () => {
const userData =
amount && duration && receiver
? getForwarderStakeUserData({
amount,
duration,
receiverAddress: receiver
})
: '0x'

return {
address: settings.contracts.forwarderOnMainnet,
abi: ForwarderABI,
functionName: 'call',
args: [amount, settings.contracts.forwarderOnGnosis, userData, pNetworkNetworkIds.gnosis],
enabled: stakeEnabled,
chainId: mainnet.id
}
}
const getStakeData = migration
? migrationPrepareData()
: {
address: settings.contracts.stakingManager,
abi: StakingManagerABI,
functionName: 'stake',
args: [onChainAmount, duration * SECONDS_IN_ONE_DAY, receiver],
enabled: stakeEnabled
}
const { config: stakeConfigs } = usePrepareContractWrite(getStakeData)
const { write: stake, error: stakeError, data: stakeData, status: stakeStatus } = useContractWrite(stakeConfigs)

const { isLoading: isApproving } = useWaitForTransaction({
Expand Down

0 comments on commit 7a51768

Please sign in to comment.