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
2 changes: 2 additions & 0 deletions contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ public override Empty TransferToContract(TransferToContractInput input)
public override Empty AdvanceResourceToken(AdvanceResourceTokenInput input)
{
AssertValidInputAddress(input.ContractAddress);
AssertValidSymbolAndAmount(input.ResourceTokenSymbol, input.Amount);
Assert(
Context.Variables.GetStringArray(TokenContractConstants.PayTxFeeSymbolListName)
.Contains(input.ResourceTokenSymbol),
Expand All @@ -426,6 +427,7 @@ public override Empty TakeResourceTokenBack(TakeResourceTokenBackInput input)
{
Assert(!string.IsNullOrWhiteSpace(input.ResourceTokenSymbol), "Invalid input resource token symbol.");
AssertValidInputAddress(input.ContractAddress);
Assert(input.Amount > 0, "Invalid amount.");
Comment thread
jason-aelf marked this conversation as resolved.
var advancedAmount =
State.AdvancedResourceToken[input.ContractAddress][Context.Sender][input.ResourceTokenSymbol];
Assert(advancedAmount >= input.Amount, "Can't take back that more.");
Expand Down
2 changes: 1 addition & 1 deletion contract/AElf.Contracts.Profit/ProfitContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ private Dictionary<string, long> ProfitAllPeriods(Scheme scheme, ProfitDetail pr
});
}

lastProfitPeriod = period + 1;
lastProfitPeriod = Math.Max(lastProfitPeriod, period + 1);
Comment thread
jason-aelf marked this conversation as resolved.
}

totalAmount = totalAmount.Add(amount);
Expand Down
13 changes: 13 additions & 0 deletions contract/AElf.Contracts.Vote/VoteContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ public override Empty Vote(VoteInput input)
amount = votingItem.TicketCost.Mul(currentVotesCount);
}

Assert(amount > 0, "Invalid amount.");
Comment thread
jason-aelf marked this conversation as resolved.

var existingRecord = State.VotingRecords[input.VoteId];
if (existingRecord != null)
{
Assert(input.IsChangeTarget, "VoteId already exists.");
Assert(existingRecord.IsWithdrawn, "VoteId already exists and not withdrawn.");
Assert(existingRecord.VotingItemId == input.VotingItemId, "VoteId belongs to a different voting item.");
Assert(existingRecord.Voter == input.Voter, "VoteId belongs to a different voter.");
}
Comment thread
jason-aelf marked this conversation as resolved.

var votingRecord = new VotingRecord
{
VotingItemId = input.VotingItemId,
Expand Down Expand Up @@ -199,6 +210,8 @@ public override Empty Withdraw(WithdrawInput input)
else
Assert(votingItem.Sponsor == Context.Sender, "No permission to withdraw votes of others.");

Assert(!votingRecord.IsWithdrawn, "Vote already withdrawn.");

// Update VotingRecord.
votingRecord.IsWithdrawn = true;
votingRecord.WithdrawTimestamp = Context.CurrentBlockTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,58 @@ await TokenContractStub.AdvanceResourceToken.SendAsync(new AdvanceResourceTokenI
return contractAddress;
}

[Fact]
public async Task TokenContract_AdvanceResourceToken_Negative_Amount_Test()
{
var contractAddress = await TokenContract_AdvanceResourceToken_Test();

await TokenContractStub.Transfer.SendAsync(new TransferInput
{
Symbol = "ELF",
Amount = 100000000,
To = OtherAddress
});

// Check balance of other address.
{
var balance = await OtherTokenContractStub.GetBalance.CallAsync(new GetBalanceInput
{
Owner = OtherAddress,
Symbol = ResourceTokenSymbol
});
balance.Balance.ShouldBe(0);
}

var executionResult = await OtherTokenContractStub.AdvanceResourceToken.SendWithExceptionAsync(new AdvanceResourceTokenInput
{
ContractAddress = contractAddress,
Amount = -Amount,
ResourceTokenSymbol = ResourceTokenSymbol
});

executionResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed);
executionResult.TransactionResult.Error.ShouldContain("Invalid amount");
// Check balance of contract address.
{
var balance = await OtherTokenContractStub.GetBalance.CallAsync(new GetBalanceInput
{
Owner = contractAddress,
Symbol = ResourceTokenSymbol
});
balance.Balance.ShouldBe(Amount);
}

// Check balance of developer.
{
var balance = await OtherTokenContractStub.GetBalance.CallAsync(new GetBalanceInput
{
Owner = OtherAddress,
Symbol = ResourceTokenSymbol
});
balance.Balance.ShouldBe(0);
}
}

[Fact]
public async Task TokenContract_TakeResourceTokenBack_Test()
{
Expand Down Expand Up @@ -163,6 +215,22 @@ public async Task TokenContract_TakeResourceTokenBack_Exceed_Test()
result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed);
result.TransactionResult.Error.ShouldContain("Can't take back that more.");
}

[Fact]
public async Task TokenContract_TakeResourceTokenBack_Negative_Amount_Test()
{
var contractAddress = await TokenContract_AdvanceResourceToken_Test();

var result = await TokenContractStub.TakeResourceTokenBack.SendWithExceptionAsync(new TakeResourceTokenBackInput
{
ContractAddress = contractAddress,
Amount = -Amount,
ResourceTokenSymbol = ResourceTokenSymbol
});

result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed);
result.TransactionResult.Error.ShouldContain("Invalid amount");
}

[Fact]
public async Task SetControllerForManageConnector_Test()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using AElf.Contracts.Treasury;
using AElf.Contracts.Vote;
using AElf.Cryptography.ECDSA;
using AElf.Types;
using Volo.Abp.Threading;

namespace AElf.Contracts.EconomicSystem.Tests;
Expand All @@ -30,6 +31,10 @@ public class EconomicSystemTestBase : EconomicContractsTestBase
internal TokenContractImplContainer.TokenContractImplStub TokenContractImplStub =>
GetTokenContractImplTester(BootMinerKeyPair);

protected Address OtherAddress => Address.FromPublicKey(Accounts[1].KeyPair.PublicKey);
internal TokenContractImplContainer.TokenContractImplStub OtherTokenContractStub =>
GetTokenContractTester(Accounts[1].KeyPair);

internal TokenHolderContractImplContainer.TokenHolderContractImplStub TokenHolderStub =>
GetTokenHolderTester(BootMinerKeyPair);

Expand Down
74 changes: 74 additions & 0 deletions test/AElf.Contracts.Election.Tests/BVT/ElectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,80 @@ await ElectionContractStub.GetElectorVoteWithRecords.CallAsync(
}
}

[Fact]
public async Task ElectionContract_Withdraw_Succeeds_When_Delegated_VoteId_Collision_Is_Rejected_Test()
{
const int amount = 100;
const int lockTime = 7 * 60 * 60 * 24;

var candidateKeyPair = ValidationDataCenterKeyPairs[0];
await AnnounceElectionAsync(candidateKeyPair);
var candidatePubkey = candidateKeyPair.PublicKey.ToHex();

var voterKeyPair = VoterKeyPairs[0];
var otherVoterKeyPair = VoterKeyPairs[1];
var voterAddress = Address.FromPublicKey(voterKeyPair.PublicKey);

var voteResult = await VoteToCandidateAsync(voterKeyPair, candidatePubkey, lockTime, amount);
voteResult.Status.ShouldBe(TransactionResultStatus.Mined);
var voteId = Hash.Parser.ParseFrom(voteResult.ReturnValue);

var originalRecord = await VoteContractStub.GetVotingRecord.CallAsync(voteId);
originalRecord.VotingItemId.ShouldBe(MinerElectionVotingItemId);
originalRecord.Voter.ShouldBe(voterAddress);
originalRecord.Option.ShouldBe(candidatePubkey);

var otherVoteStub = GetVoteContractTester(otherVoterKeyPair);
var otherRegisterTime = TimestampHelper.GetUtcNow();
var otherRegisterInput = new VotingRegisterInput
{
AcceptedCurrency = ElectionContractTestConstants.NativeTokenSymbol,
IsLockToken = false,
StartTimestamp = otherRegisterTime,
EndTimestamp = otherRegisterTime.AddDays(1),
TotalSnapshotNumber = 1,
Options = { candidatePubkey }
};
var registerResult = await otherVoteStub.Register.SendAsync(otherRegisterInput);
registerResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined);

var otherRegisterInputForHash = otherRegisterInput.Clone();
otherRegisterInputForHash.Options.Clear();
var otherVotingItemId = HashHelper.ConcatAndCompute(HashHelper.ComputeFrom(otherRegisterInputForHash),
HashHelper.ComputeFrom(Address.FromPublicKey(otherVoterKeyPair.PublicKey)));

var collisionResult = await otherVoteStub.Vote.SendWithExceptionAsync(new VoteInput
{
VotingItemId = otherVotingItemId,
VoteId = voteId,
Voter = voterAddress,
Option = candidatePubkey,
Amount = 1
});
collisionResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed);
collisionResult.TransactionResult.Error.ShouldContain("VoteId already exists.");

var recordAfterRejectedCollision = await VoteContractStub.GetVotingRecord.CallAsync(voteId);
recordAfterRejectedCollision.VotingItemId.ShouldBe(MinerElectionVotingItemId);
recordAfterRejectedCollision.Voter.ShouldBe(voterAddress);
recordAfterRejectedCollision.Amount.ShouldBe(amount);
recordAfterRejectedCollision.Option.ShouldBe(candidatePubkey);
recordAfterRejectedCollision.IsWithdrawn.ShouldBeFalse();

BlockTimeProvider.SetBlockTime(recordAfterRejectedCollision.VoteTimestamp.AddSeconds(lockTime + 1000));

var withdrawResult = await WithdrawVotes(voterKeyPair, voteId);
withdrawResult.Error.ShouldBeEmpty();
withdrawResult.Status.ShouldBe(TransactionResultStatus.Mined);

var electorVote = await ElectionContractStub.GetElectorVoteWithAllRecords.CallAsync(new StringValue
{
Value = voterKeyPair.PublicKey.ToHex()
});
electorVote.ActiveVotingRecords.Select(record => record.VoteId).ShouldNotContain(voteId);
electorVote.WithdrawnVotesRecords.Select(record => record.VoteId).ShouldContain(voteId);
}

[Fact]
public async Task ElectionContract_GetCandidates_Test()
{
Expand Down
Loading
Loading