Skip to content

Commit 4a7ad7b

Browse files
committed
returned min_units_for_deposit as min_campaign_budget
1 parent b6226d6 commit 4a7ad7b

File tree

11 files changed

+151
-97
lines changed

11 files changed

+151
-97
lines changed

adapter/src/dummy.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ mod test {
209209
let channel_context = ChainOf {
210210
context: channel,
211211
token: TokenInfo {
212+
min_campaign_budget: 1_u64.into(),
212213
min_validator_fee: 1_u64.into(),
213214
precision: NonZeroU8::new(UnifiedNum::PRECISION).expect("Non zero u8"),
214215
address: channel.token,

adapter/src/ethereum/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ mod test {
684684
let web3 = GANACHE_1.init_web3().expect("Init web3");
685685

686686
// deploy contracts
687-
let token = Erc20Token::deploy(&web3)
687+
let token = Erc20Token::deploy(&web3, 1_000)
688688
.await
689689
.expect("Correct parameters are passed to the Token constructor.");
690690

adapter/src/ethereum/test_util.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ impl Erc20Token {
258258
}
259259

260260
/// Deploys the Mock Token contract from [`LEADER`]
261-
pub async fn deploy(web3: &Web3<Http>) -> web3::contract::Result<Self> {
261+
pub async fn deploy(
262+
web3: &Web3<Http>,
263+
min_campaign_budget: u64,
264+
) -> web3::contract::Result<Self> {
262265
let token_contract = Contract::deploy(web3.eth(), &MOCK_TOKEN_ABI)
263266
.expect("Invalid ABI of Mock Token contract")
264267
.confirmations(0)
@@ -272,6 +275,7 @@ impl Erc20Token {
272275
let token_address = Address::from(token_contract.address().to_fixed_bytes());
273276

274277
let token_info = TokenInfo {
278+
min_campaign_budget: BigNum::from(min_campaign_budget),
275279
precision: NonZeroU8::new(18).expect("should create NonZeroU8"),
276280
// 0.000_001
277281
min_validator_fee: BigNum::from(1_000_000_000_000),

adapter/tests/dummy.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ async fn main() {
8282
let channel_context = ChainOf {
8383
context: DUMMY_CAMPAIGN.channel,
8484
token: TokenInfo {
85+
min_campaign_budget: 1_u64.into(),
8586
min_validator_fee: 1_u64.into(),
8687
precision: NonZeroU8::new(18).unwrap(),
8788
address: "0x6B83e7D6B72c098d48968441e0d05658dc17Adb9"

docs/config/dev.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,23 @@ sweeper = '0x333420fc6a897356e69b62417cd17ff012177d2b'
5454
[chain."Ethereum Mainnet".token.DAI]
5555
address = '0x6B175474E89094C44Da98b954EedeAC495271d0F' # checked
5656
precision = 18
57+
# 1 * 10^-10 = 0.0_000_000_001
58+
min_campaign_budget = '100000000'
5759
min_validator_fee = '100000000'
5860

5961
[chain."Ethereum Mainnet".token.USDT]
6062
address = '0xdAC17F958D2ee523a2206206994597C13D831ec7' # checked
6163
precision = 6
64+
# 1.000_000
65+
min_campaign_budget = '1000000'
6266
# 0.001
6367
min_validator_fee = '1000'
6468

6569
[chain."Ethereum Mainnet".token.USDC]
6670
address = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' # checked
6771
precision = 6
72+
# 1.000_000
73+
min_campaign_budget = '1000000'
6874
# 0.001
6975
min_validator_fee = '1000'
7076

@@ -80,6 +86,8 @@ sweeper = '0x333420fc6a897356e69b62417cd17ff012177d2b'
8086
[chain."Ethereum Ropsten".token.DAI]
8187
address = '0x65600c50Ea42e225368Ded6c3789a539284aA62C' # checked
8288
precision = 18
89+
# 1 * 10^-10 = 0.0_000_000_001
90+
min_campaign_budget = '100000000'
8391
min_validator_fee = '100000000'
8492

8593
# [chain."Ethereum Ropsten".token.USDT]

docs/config/ganache.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ outpace = '0x26CBc2eAAe377f6Ac4b73a982CD1125eF4CEC96f'
5656
[chain."Ganache #1".token."Mocked TOKEN 1"]
5757
address = '0x12a28f2bfBFfDf5842657235cC058242f40fDEa6' # checked
5858
precision = 18
59+
# 1 * 10^18 = 1.0000 TOKEN
60+
min_campaign_budget = '1000000000000000000'
5961
# multiplier = 10^12 - 10^18 (token precision) = 10^-6
6062
# min_validator_fee = 1 * 10^-6 = 0.000_001
6163
min_validator_fee = '1000000000000'
@@ -70,6 +72,8 @@ outpace = '0xAbc27d46a458E2e49DaBfEf45ca74dEDBAc3DD06'
7072
[chain."Ganache #1337".token."Mocked TOKEN 1337"]
7173
address = '0x2bcaf6968aec8a3b5126fbfab5fd419da6e8ad8e' # checked
7274
precision = 18
75+
# 1 * 10^18 = 1.0000 TOKEN
76+
min_campaign_budget = '1000000000000000000'
7377
# multiplier = 10^12 - 10^18 (token precision) = 10^-6
7478
# min_validator_fee = 1 * 10^-6 = 0.000_001
7579
min_validator_fee = '1000000000000'

docs/config/prod.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,25 @@ admins = ['0x5d6A3F1AD7b124ecDFDf4841D9bB246eD5fBF04c']
3131
# DAI
3232
# Polygon: https://polygonscan.com/token/0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063
3333
address = '0x6b175474e89094c44da98b954eedeac495271d0f'
34+
# 1 * 10^-10 = 0.0_000_000_001
35+
min_campaign_budget = '100000000'
3436
min_validator_fee = '100000000'
3537
precision = 18
3638

3739
[[token_address_whitelist]]
3840
# SAI
3941
address = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'
42+
# 1 * 10^-10 = 0.0_000_000_001
43+
min_campaign_budget = '100000000'
4044
min_validator_fee = '100000000'
4145
precision = 18
4246

4347
[[token_address_whitelist]]
4448
# USDT
4549
# Polygon: https://polygonscan.com/token/0xc2132d05d31c914a87c6611c10748aeb04b58e8f
4650
address = '0xdac17f958d2ee523a2206206994597c13d831ec7'
51+
# 1.000_000
52+
min_campaign_budget = '1000000'
4753
# 0.001
4854
min_validator_fee = '1000'
4955
precision = 6
@@ -52,6 +58,8 @@ precision = 6
5258
# USDC
5359
# Polygon: https://polygonscan.com/token/0x2791bca1f2de4661ed88a30c99a7a9449aa84174
5460
address = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
61+
# 1.000_000
62+
min_campaign_budget = '100000000'
5563
# 0.001
5664
min_validator_fee = '1000'
5765
precision = 6

primitives/src/campaign_validator.rs

Lines changed: 117 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub enum Validation {
2424
UnlistedValidator,
2525
UnlistedCreator,
2626
UnlistedAsset,
27+
MinimumDepositNotMet,
2728
MinimumValidatorFeeNotMet,
2829
FeeConstraintViolated,
2930
}
@@ -71,6 +72,15 @@ impl Validator for Campaign {
7172
.find_chain_of(self.channel.token)
7273
.ok_or(Validation::UnlistedAsset)?;
7374

75+
// Check if the campaign budget is above the minimum deposit configured
76+
if self
77+
.budget
78+
.to_precision(chain_context.token.precision.get())
79+
< chain_context.token.min_campaign_budget
80+
{
81+
return Err(Validation::MinimumDepositNotMet.into());
82+
}
83+
7484
// Check if the validator fee is greater than the minimum configured fee
7585
if whoami_validator
7686
.fee
@@ -289,6 +299,20 @@ mod test {
289299
);
290300
}
291301

302+
// budget < min_deposit
303+
{
304+
let mut campaign = DUMMY_CAMPAIGN.clone();
305+
campaign.budget = UnifiedNum::from_u64(0);
306+
307+
let validation_error = campaign
308+
.validate(&config, IDS[&LEADER])
309+
.expect_err("Should trigger validation error");
310+
assert_eq!(
311+
Error::Validation(Validation::MinimumDepositNotMet),
312+
validation_error,
313+
);
314+
}
315+
292316
// validator_fee < min_fee
293317
{
294318
let campaign = DUMMY_CAMPAIGN.clone();
@@ -316,99 +340,99 @@ mod test {
316340
);
317341
}
318342

319-
// let sum_fees = |validators: &Validators| -> UnifiedNum {
320-
// validators
321-
// .iter()
322-
// .map(|validator| validator.fee)
323-
// .sum::<Option<_>>()
324-
// .expect("Validators sum of fees should not overflow")
325-
// };
326-
327-
// // total_fee > budget
328-
// // budget = total_fee - 1
329-
// {
330-
// let mut campaign = DUMMY_CAMPAIGN.clone();
331-
// let campaign_token = config.find_chain_of(campaign.channel.token).unwrap().token;
332-
333-
// // makes the sum of all validator fees = 2 * min token units for deposit
334-
// campaign.validators = {
335-
// let new_validators = campaign
336-
// .validators
337-
// .iter()
338-
// .map(|validator| {
339-
// let mut new_validator = validator.clone();
340-
// new_validator.fee = UnifiedNum::from_precision(
341-
// campaign_token.min_token_units_for_deposit.clone(),
342-
// campaign_token.precision.into(),
343-
// )
344-
// .expect("Should not overflow");
345-
346-
// new_validator
347-
// })
348-
// .collect::<Vec<_>>();
349-
350-
// assert_eq!(
351-
// 2,
352-
// new_validators.len(),
353-
// "Dummy Campaign validators should always be 2 - a leader & a follower"
354-
// );
355-
356-
// Validators::new((new_validators[0].clone(), new_validators[1].clone()))
357-
// };
358-
359-
// campaign.budget = sum_fees(&campaign.validators) - UnifiedNum::from(1);
360-
361-
// let validation_error = campaign
362-
// .validate(&config, IDS[&LEADER])
363-
// .expect_err("Should trigger validation error");
364-
// assert_eq!(
365-
// Error::Validation(Validation::FeeConstraintViolated),
366-
// validation_error,
367-
// );
368-
// }
369-
370-
// // total_fee = budget
371-
// {
372-
// let mut campaign = DUMMY_CAMPAIGN.clone();
373-
374-
// let campaign_token = config.find_chain_of(campaign.channel.token).unwrap().token;
375-
376-
// // makes the sum of all validator fees = 2 * min token units for deposit
377-
// campaign.validators = {
378-
// let new_validators = campaign
379-
// .validators
380-
// .iter()
381-
// .map(|validator| {
382-
// let mut new_validator = validator.clone();
383-
// new_validator.fee = UnifiedNum::from_precision(
384-
// campaign_token.min_token_units_for_deposit.clone(),
385-
// campaign_token.precision.into(),
386-
// )
387-
// .expect("Should not overflow");
388-
389-
// new_validator
390-
// })
391-
// .collect::<Vec<_>>();
392-
393-
// assert_eq!(
394-
// 2,
395-
// new_validators.len(),
396-
// "Dummy Campaign validators should always be 2 - a leader & a follower"
397-
// );
398-
399-
// Validators::new((new_validators[0].clone(), new_validators[1].clone()))
400-
// };
401-
402-
// campaign.budget = sum_fees(&campaign.validators);
403-
404-
// let validation_error = campaign
405-
// .validate(&config, IDS[&LEADER])
406-
// .expect_err("Should trigger validation error");
407-
// assert_eq!(
408-
// Error::Validation(Validation::FeeConstraintViolated),
409-
// validation_error,
410-
// );
411-
// }
343+
let sum_fees = |validators: &Validators| -> UnifiedNum {
344+
validators
345+
.iter()
346+
.map(|validator| validator.fee)
347+
.sum::<Option<_>>()
348+
.expect("Validators sum of fees should not overflow")
349+
};
350+
351+
// total_fee > budget
352+
// budget = total_fee - 1
353+
{
354+
let mut campaign = DUMMY_CAMPAIGN.clone();
355+
let campaign_token = config.find_chain_of(campaign.channel.token).unwrap().token;
356+
357+
// makes the sum of all validator fees = 2 * min token units for deposit
358+
campaign.validators = {
359+
let new_validators = campaign
360+
.validators
361+
.iter()
362+
.map(|validator| {
363+
let mut new_validator = validator.clone();
364+
new_validator.fee = UnifiedNum::from_precision(
365+
campaign_token.min_campaign_budget.clone(),
366+
campaign_token.precision.into(),
367+
)
368+
.expect("Should not overflow");
369+
370+
new_validator
371+
})
372+
.collect::<Vec<_>>();
373+
374+
assert_eq!(
375+
2,
376+
new_validators.len(),
377+
"Dummy Campaign validators should always be 2 - a leader & a follower"
378+
);
379+
380+
Validators::new((new_validators[0].clone(), new_validators[1].clone()))
381+
};
382+
383+
campaign.budget = sum_fees(&campaign.validators) - UnifiedNum::from(1);
384+
385+
let validation_error = campaign
386+
.validate(&config, IDS[&LEADER])
387+
.expect_err("Should trigger validation error");
388+
assert_eq!(
389+
Error::Validation(Validation::FeeConstraintViolated),
390+
validation_error,
391+
);
392+
}
393+
394+
// total_fee = budget
395+
{
396+
let mut campaign = DUMMY_CAMPAIGN.clone();
397+
398+
let campaign_token = config.find_chain_of(campaign.channel.token).unwrap().token;
399+
400+
// makes the sum of all validator fees = 2 * min token units for deposit
401+
campaign.validators = {
402+
let new_validators = campaign
403+
.validators
404+
.iter()
405+
.map(|validator| {
406+
let mut new_validator = validator.clone();
407+
new_validator.fee = UnifiedNum::from_precision(
408+
campaign_token.min_campaign_budget.clone(),
409+
campaign_token.precision.into(),
410+
)
411+
.expect("Should not overflow");
412+
413+
new_validator
414+
})
415+
.collect::<Vec<_>>();
416+
417+
assert_eq!(
418+
2,
419+
new_validators.len(),
420+
"Dummy Campaign validators should always be 2 - a leader & a follower"
421+
);
422+
423+
Validators::new((new_validators[0].clone(), new_validators[1].clone()))
424+
};
425+
426+
campaign.budget = sum_fees(&campaign.validators);
427+
428+
let validation_error = campaign
429+
.validate(&config, IDS[&LEADER])
430+
.expect_err("Should trigger validation error");
431+
assert_eq!(
432+
Error::Validation(Validation::FeeConstraintViolated),
433+
validation_error,
434+
);
435+
}
412436

413437
// should validate
414438
{

primitives/src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ impl ChainInfo {
164164
/// Precision can differ for the same token from one [`Chain`] to another.
165165
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)]
166166
pub struct TokenInfo {
167+
pub min_campaign_budget: BigNum,
167168
pub min_validator_fee: BigNum,
168169
pub precision: NonZeroU8,
169170
pub address: Address,

sentry/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ redis = { version = "0.21", features = ["aio", "tokio-comp"] }
4040
deadpool = "0.9"
4141
deadpool-postgres = "0.10"
4242
# Should be the same version as in `primitives` and `deadpool-postgres`!
43-
tokio-postgres = { version = "0.7", features = ["with-chrono-0_4", "with-serde_json-1"] }
43+
tokio-postgres = { version = "0.7", features = [
44+
"with-chrono-0_4",
45+
"with-serde_json-1",
46+
] }
4447
postgres-types = { version = "0.2", features = [
4548
"derive",
4649
"with-chrono-0_4",

0 commit comments

Comments
 (0)