Percentage calculation

Hi,
I am developing a dao dapp And I am stuck at a condotion…
If the proposal gets more than 75% of yes vote I want to give rewards to yes voters, and if votes are less then some penalty.How can I do that?

75% = 3/4, so

if (3*cnt_vote_all < 4*cnt_vote_yes) {
  // give reward...
}
2 Likes

@Maugli 's solution is correct as long as the number of votes multiplied by 4 is always less than 2^64-1.
It should be the case in most settings.

In general, when doing arithmetic, it’s very important to check that no operation can overflow (result higher than 2^64-1 in this case) or underflow (e.g., getting a negative number).

@fabrice I didn’t get the reference for (2^64-1).
Why do we have to check that exactly?

@Maugli Thanks a lot

2^64 - 1 = 2 to the power 64 minus 1 = 18446744073709551615 is the largest number that can be represented with 64 unsigned bits, which is what TEAL used.
See Integer (computer science) - Wikipedia also.

If at any point, you make an operation that goes above this number, your program immediately fails.
So you need to be sure that 4*cnt_vote_yes < 18446744073709551615)

1 Like

Oh okay… Thanks a lot!!

I tried this soultion but my then I get an error "unsupported operand type(s) for *: ‘int’ and ‘App’ "
I am using this repo of DAO for reference.

https://github.com/scale-it/algo-builder/tree/master/examples/dao

This is my code

scratchvar_yes_count.store(App.globalGet(Bytes("Yes_count"))),
scratchvar_no_count.store(App.globalGet(Bytes("No_count"))),
scratchvar_total_count.store((App.globalGet(Bytes("Yes_count")))+(App.globalGet(Bytes("No_count")))),

If(3*App.globalGet(proposal_max_stake) < 4*App.globalPut("Yes_count"), scratchvar_yes_count),
        Approve(),        

You should compile with Mode.Application

compiled = compileTeal(approval_program(), mode=Mode.Application, version=4)

Also, use Int(3) and Int(4), instead of 3 and 4 in the multiply operation:

    # Scratch space to store the vote yes and no cnt
    vote_yes_cnt = ScratchVar(TealType.uint64)
    vote_no_cnt = ScratchVar(TealType.uint64)
    vote_total_cnt = ScratchVar(TealType.uint64)
    vote_result = ScratchVar(TealType.uint64)

    # Check if vote_yes_cnt > 3/4 * (vote_yes_cnt + vote_no_cnt)
    # Check if 4*vote_yes_cnt > 3*vote_total_cnt
    claim_vote_op = Seq([
            vote_yes_cnt.store(App.globalGet(Bytes(key_vote_yes_cnt))),
            vote_no_cnt.store(App.globalGet(Bytes(key_vote_no_cnt))),
            vote_total_cnt.store(vote_yes_cnt.load()+vote_no_cnt.load()),
            vote_result.store(Int(0)),
            If (Int(4)*vote_yes_cnt.load() > Int(3)*vote_total_cnt.load(), vote_result.store(Int(1))),
            vote_result.load()
        ])
2 Likes

Thanks a lot…I try this solution!!

Hi.
I tried this soultion by you and I am still getting and error.
This is my code.

on_execute = Seq(
        total_count.store(yes_count.load()+no_count.load()),
        vote_result.store(Int(0)),
        If(App.globalGet(proposal_start_time) <= Global.latest_timestamp()).Then(
            Seq(
                Assert(App.globalGet(proposal_min_stake) <= Btoi(Txn.application_args[1])),
                Assert(Int(4)*yes_count.load() > Int(3)*total_count.load(), vote_result.store(Int(1))),
                vote_result.load()
            )
        )
        .Else(App.globalGet(proposal_end_time) > Global.latest_timestamp()),
        Reject(),
        )      

The error I am getting is

Traceback (most recent call last):
  File "contracts2.py", line 157, in <module>
    compiled = compileTeal(approval_program(), mode=Mode.Application, version=5)
  File "contracts2.py", line 121, in approval_program
    Assert(Int(4)*yes_count.load() > Int(3)*total_count.load(), vote_result.store(Int(1))),
TypeError: __init__() takes 2 positional arguments but 3 were given

What is going wrong here I am not getting it.

Maybe an ‘if’ is missing.

I am getting the same error with if statement so I tried with ‘assert’

    total_count = ScratchVar(TealType.uint64)
    yes_count = ScratchVar(TealType.uint64)
    no_count = ScratchVar(TealType.uint64)
    vote_result1 = ScratchVar(TealType.uint64)
    proposal_min_stake = "k5"
    proposal_start_time = "k6"
    proposal_end_time = "k7"

    on_execute_precond = Seq([
        yes_count.store(Int(0)),
        no_count.store(Int(0)),
        #total_count.store(Int(0)),
        #vote_result1.store(Int(0)),
        Int(1)
        ])
    
    on_execute = Seq([
        total_count.store(yes_count.load()+no_count.load()),
        vote_result1.store(Int(0)),
        If(App.globalGet(Bytes(proposal_start_time)) <= Global.latest_timestamp())
        .Then(
            Seq([
                Assert(App.globalGet(Bytes(proposal_min_stake)) <= Btoi(Txn.application_args[1])),
                If(Int(4)*yes_count.load() > Int(3)*total_count.load(), vote_result1.store(Int(1))),
                vote_result1.load()
            ])
        )
        .ElseIf(App.globalGet(Bytes(proposal_end_time)) > Global.latest_timestamp())
        .Then(Reject()),
    ])

    claim_vote = And(on_execute_precond, on_execute)

So, as you see, I changed Seq([…]), also If then logic a little. I hope this helps.
I haven’t tested it, but at least it compiles without errors. Note: you must initialize scratch vars before use, that is I do in on_execute_precond. Change this code.
Also,@fabrice, please send an Algorand Discord invite to @isha, please. There you can find
a lot of usefuld groups, i.e pyTeal as well.

Great thanks…I think this will help!!

You are welcome.
Another note, as I see, Seq() is valid now, you can omit the [ and ].

1 Like