Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion contracts/src/withdraw/Withdraw.sol
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ contract Withdraw is InitializableUsingRegistry, IWithdraw {
IERC20 property = IERC20(_property);
uint256 balance = property.balanceOf(_user);
uint256 totalSupply = property.totalSupply();
uint256 unitPriceCap = (_cap - _lastRewardCap) / totalSupply;
uint256 unitPriceCap = _cap >= _lastRewardCap
? (_cap - _lastRewardCap) / totalSupply
: _cap / totalSupply; // If this user has held this tokens since before this tokens got its first staking, _lastRewardCap is expected to larger than _cap. In this case, it can treat _cap as the latest range of the value.
return (unitPriceCap * balance).divBasis();
}

Expand Down
24 changes: 24 additions & 0 deletions migrations/update/1_update-withdraw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const handler = async function (deployer, network) {
if (network === 'test') {
return
}

const adminAddress = process.env.ADMIN!
const proxyAddress = process.env.WITHDRAW_PROXY!
console.log(`admin address:${adminAddress}`)
console.log(`withdraw proxy address:${proxyAddress}`)

const logic = artifacts.require('Withdraw')
await deployer.deploy(logic)
const logicInstance = await logic.deployed()
console.log(`logic address:${logicInstance.address}`)

const adminInstance = await artifacts.require('DevAdmin').at(adminAddress)
await adminInstance.upgrade(proxyAddress, logicInstance.address)

const implAddress = await adminInstance.getProxyImplementation(proxyAddress)

console.log(`impl address:${implAddress}`)
} as Truffle.Migration

export = handler
78 changes: 72 additions & 6 deletions test/withdraw/withdraw-scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ contract('WithdrawTest', ([deployer, user1, user2, user3, user4]) => {
})
})

describe('Withdraw; calculateonlyRewardAmount', () => {
describe('Withdraw; calculateRewardAmount', () => {
type calcResult = {
readonly value: BigNumber
readonly reword: BigNumber
Expand Down Expand Up @@ -385,11 +385,13 @@ contract('WithdrawTest', ([deployer, user1, user2, user3, user4]) => {
.div(1e18)
.div(1e18)
.integerValue(BigNumber.ROUND_DOWN)
const unitPriceCap = cap
.minus(lastRewardCap)
.times(1e18)
.div(totalSupply)
.integerValue(BigNumber.ROUND_DOWN)
const unitPriceCap = cap.isGreaterThanOrEqualTo(lastRewardCap)
? cap
.minus(lastRewardCap)
.times(1e18)
.div(totalSupply)
.integerValue(BigNumber.ROUND_DOWN)
: cap.times(1e18).div(totalSupply).integerValue(BigNumber.ROUND_DOWN)
const capped = unitPriceCap
.times(balanceOfUser)
.div(1e18)
Expand Down Expand Up @@ -1357,5 +1359,69 @@ contract('WithdrawTest', ([deployer, user1, user2, user3, user4]) => {
})
})
})

describe('scenario: multiple properties: transfer tokens before got its first staking', () => {
let dev: DevProtocolInstance
let property1: PropertyInstance
let property2: PropertyInstance
let calc: Calculator

const alice = deployer
const bob = user1
const carol = user2
const dave = user4

before(async () => {
;[dev, , property1] = await init(deployer, user3)
calc = createCalculator(dev)
const aliceBalance = await dev.dev.balanceOf(alice).then(toBigNumber)
await dev.dev.mint(bob, aliceBalance)
await dev.dev.mint(carol, aliceBalance)
await dev.dev.mint(dave, aliceBalance)
property2 = await artifacts
.require('Property')
.at(
getPropertyAddress(
await dev.propertyFactory.create('test2', 'TEST2', bob)
)
)
await dev.metricsFactory.__setMetricsCountPerProperty(
property2.address,
1
)
await dev.dev.approve(dev.lockup.address, '50000000000000000000000', {
from: dave,
})
await dev.lockup.depositToProperty(
property1.address,
'10000000000000000000000',
{
from: dave,
}
)
await forwardBlockTimestamp(3)
})

it('transfer tokens before got its first staking', async () => {
await property2.transfer(alice, '3000000000000000000000000', {
from: bob,
})
await dev.lockup.depositToProperty(
property2.address,
'10000000000000000000000',
{
from: dave,
}
)
await forwardBlockTimestamp(3)
const calcResult = await calc(property2, alice)
await validateCalculateRewardAmountData(
dev,
property2,
alice,
calcResult
)
})
})
})
})