> For the complete documentation index, see [llms.txt](https://fusee.gitbook.io/mx-sdk-as/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://fusee.gitbook.io/mx-sdk-as/the-flip-smart-contract/the-flip-smart-contract-part-6-bet-logic.md).

# The Flip Smart Contract part 6 : Bet logic

## Setting the base percentage

Remember in the part 4 we talked about percentages. We said hundred percentage is 10,000 due to VM limitation using integers only. For future computation we need to store this constant inside the contract code :&#x20;

```typescript
const HUNDRED_PERCENT: u64 = 10_000

@contract
abstract class FlipContract extends ContractBase {
// --- rest of the code ---
}
```

{% hint style="warning" %}
Notice the type of `HUNDRED_PERCENT`. It's the AssemblyScript's native `u64`, not the mx-sdk-as's one. Instantiate classes statically may lead to issue when deploying the contract. Avoid it and prefers use primitive types when creating globals variables.
{% endhint %}

## Initialising the contract

We didn't had a `constructor` to our contract yet ! Time to add one inside the `FlipContract` class :&#x20;

```typescript
constructor(
    ownerPercentFees: ManagedU64,
    bountyPercentFees: ManagedU64,
    minimumBlockBounty: ManagedU64
) {
    super()
    this.ownerPercentFees().set(ownerPercentFees)
    this.bountyPercentFees().set(bountyPercentFees)

    this.require(
        minimumBlockBounty > ManageddU64.zero(),
        "minimumBlockBounty is zero"
    )

    this.minimumBlockBounty().set(minimumBlockBounty)
}
```

The contract's constructor is called each time the contract is deployed or updated (if allowed to be). Here we simply initialise the storage.

We do not initialise `maximumBet` and `maximumBetPercent` here as they are relative to a token.

## Create the flip endpoint

Next step, create the flip endpoint. Inside the `FlipContract` class add the following method :&#x20;

```typescript
flip(): void {
    // --- Step 1 ---
    const payment = this.callValue.singlePayment

    const tokenReserve = this.tokenReserve(
        payment.tokenIdentifier,
        payment.tokenNonce
    ).get()

    this.require(
        tokenReserve > BigUint.zero(),
        "no token reserve"
    )

    this.require(
        !this.maximumBet(payment.tokenIdentifier, payment.tokenNonce).isEmpty(),
        "no maximum bet"
    )

    this.require(
        !this.maximumBetPercent(payment.tokenIdentifier, payment.tokenNonce).isEmpty(),
        "no maximum bet percent"
    )

    const maximumBet = this.maximumBet(
        payment.tokenIdentifier,
        payment.tokenNonce
    ).get()

    const maximumBetPercent = this.maximumBetPercent(
        payment.tokenIdentifier,
        payment.tokenNonce
    ).get()

    const maximumBetPercentComputed = tokenReserve * maximumBetPercent.toBigUint() / BigUint.fromU64(HUNDRED_PERCENT)

    const maximumAllowedBet = maximumBet < maximumBetPercentComputed ? maximumBet : maximumBetPercentComputed

    // --- Step 2 ---
    const ownerProfits = payment.amount * this.ownerPercentFees().get().toBigUint() / BigUint.fromU64(HUNDRED_PERCENT)
    const bounty = payment.amount * this.bountyPercentFees().get().toBigUint() / BigUint.fromU64(HUNDRED_PERCENT)
    const amount = payment.amount - bounty - ownerProfits

    // --- Step 3 ---
    this.require(
        amount <= maximumAllowedBet,
        "too much bet"
    )
    
    // --- Step 4 ---
    const lastFlipId = this.lastFlipId().isEmpty() ? ManagedU64.zero() : this.lastFlipId().get()

    const flipId = lastFlipId + ManagedU64.fromValue(1)

    const flip = Flip.new(
        flipId,
        this.blockchain.caller,
        payment.tokenIdentifier,
        payment.tokenNonce,
        amount,
        bounty,
        this.blockchain.currentBlockNonce,
        this.minimumBlockBounty().get()
    )

    this.tokenReserve(
        payment.tokenIdentifier,
        payment.tokenNonce
    ).set(tokenReserve - amount)

    this.send
        .direct(
            this.blockchain.owner,
            payment.tokenIdentifier,
            payment.tokenNonce,
            ownerProfits
        )

    this.flipForId(flipId).set(flip)
    this.lastFlipId().set(flipId)
}
```

What does this code do ?

### Step 1 : Compute maximum bet limits

We need to ensure bet limits are not reached, hence we need to compute them.

Let's focus on the line `const maximumBetPercentComputed = tokenReserve * maximumBetPercent / ManagedU64.fromValue(HUNDRED_PERCENT)`, math operations order is important since numbers cannot be decimals and divisions are trucated : `50 / 100 = 0`.

Suppose tokenReserve = 10, maximumBetPercent = 1000 and HUNDRED\_PERCENT = 10\_000, `tokenReserve * maximumBetPercent / ManagedU64.fromValue(HUNDRED_PERCENT)` = `10 * 1000 / 10_000` = 10\_000 / 10\_000 = 1

Now the same computation in a different order : `maximumBetPercent / ManagedU64.fromValue(HUNDRED_PERCENT) * tokenReserve` = `1000 / 10_000 * 10` = `0 * 10 = 0`&#x20;

Always multiply before dividing.

{% hint style="info" %}
There is no max and min functions implemented for BigUint type at the moment. Theses are planned and this tutorial will updated when done.
{% endhint %}

### Step 2 : Compute amounts

We need to compute bounty and owners profits, after that can compute the real bet's amount.

### Step 3 : Ensure bet limit is not reached

This is simply done with the `this.require` function.

### Step 4 : Construct the flip object

Nothing special to say here, we get the last flip id, increment it and use all informations we have to create a new instance.

Then we update storage values : `flipForId`, `lastFlipId` and `tokenReserve`. For the last one we only remove computed amount (instead of full payment amount) since owner profits and bounty are not realised yet.

## Next up

The contract has the ability to initialise a flip, next step is to realise it !
