Type
CONTRACT
Validation date
2024-01-31 19:36:05 UTC
Fee
0 UCO

Code (1.86 KB)

@version 1

condition triggered_by: transaction, on: deposit(), as: [
  timestamp: transaction.timestamp < 1710763200,
  token_transfers: get_user_transfer_amount(transaction) > 0
]

actions triggered_by: transaction, on: deposit() do
  transfer_amount = get_user_transfer_amount(transaction)

  previous_address = Chain.get_previous_address(transaction)
  user_genesis_address = Chain.get_genesis_address(previous_address)

  State.set("reward_token_balance", get_reward_token_balance())

  deposits = nil
  if Time.now() > 1706720400 do
    res = calculate_new_rewards()
    deposits = res.deposits
    State.set("rewards_reserved", res.rewards_reserved)
    State.set("last_calculation_timestamp", res.last_calculation_timestamp)
  else
    deposits = State.get("deposits", Map.new())
  end

  user_deposit = Map.get(deposits, user_genesis_address, [amount: 0, reward_amount: 0])
  user_deposit = Map.set(user_deposit, "amount", user_deposit.amount + transfer_amount)
  deposits = Map.set(deposits, user_genesis_address, user_deposit)

  State.set("deposits", deposits)

  lp_token_deposited = State.get("lp_token_deposited", 0)
  State.set("lp_token_deposited", lp_token_deposited + transfer_amount)
end

condition triggered_by: transaction, on: claim(), as: [
  timestamp: transaction.timestamp > 1706720400,
  previous_public_key: (
    previous_address = Chain.get_previous_address()
    genesis_address = Chain.get_genesis_address(previous_address)

    deposits = State.get("deposits", Map.new())
    Map.get(deposits, genesis_address) != nil
  )
]

actions triggered_by: transaction, on: claim() do
  previous_address = Chain.get_previous_address(transaction)
  user_genesis_address = Chain.get_genesis_address(previous_address)

  State.set("reward_token_balance", get_reward_token_balance())

  res = calculate_new_rewards()
  deposits = res.deposits
  State.set("last_calculation_timestamp", res.last_calculation_timestamp)

  user_deposit = Map.get(deposits, user_genesis_address)

  if "UCO" == "UCO" do
    Contract.add_uco_transfer(to: transaction.address, amount: user_deposit.reward_amount)
  else
    Contract.add_token_transfer(
      to: transaction.address,
      amount: user_deposit.reward_amount,
      token_address: "UCO"
    )
  end

  reward_distributed = State.get("reward_distributed", 0)
  State.set("reward_distributed", reward_distributed + user_deposit.reward_amount)

  State.set("rewards_reserved", res.rewards_reserved - user_deposit.reward_amount)

  reward_token_balance = State.get("reward_token_balance")
  State.set("reward_token_balance", reward_token_balance - user_deposit.reward_amount)

  new_user_deposit = Map.set(user_deposit, "reward_amount", 0)
  deposits = Map.set(deposits, user_genesis_address, new_user_deposit)

  State.set("deposits", deposits)
end

condition triggered_by: transaction, on: withdraw(amount), as: [
  previous_public_key: (
    previous_address = Chain.get_previous_address()
    genesis_address = Chain.get_genesis_address(previous_address)

    deposits = State.get("deposits", Map.new())
    user_deposit = Map.get(deposits, genesis_address)

    user_deposit != nil && user_deposit.amount >= amount
  )
]

actions triggered_by: transaction, on: withdraw(amount) do
  previous_address = Chain.get_previous_address(transaction)
  user_genesis_address = Chain.get_genesis_address(previous_address)

  State.set("reward_token_balance", get_reward_token_balance())

  deposits = nil
  rewards_reserved = 0
  if Time.now() > 1706720400 do
    res = calculate_new_rewards()
    deposits = res.deposits
    rewards_reserved = res.rewards_reserved
    State.set("last_calculation_timestamp", res.last_calculation_timestamp)
  else
    deposits = State.get("deposits", Map.new())
    rewards_reserved = State.get("rewards_reserved", 0)
  end

  user_deposit = Map.get(deposits, user_genesis_address)

  if "UCO" == "UCO" do
    Contract.add_uco_transfer(to: transaction.address, amount: user_deposit.reward_amount)
  else
    Contract.add_token_transfer(
      to: transaction.address,
      amount: user_deposit.reward_amount,
      token_address: "UCO"
    )
  end

  Contract.add_token_transfer(
    to: transaction.address,
    amount: amount,
    token_address: 0x00006394EF24DFDC6FDFC3642FDC83827591A485704BB997221C0B9F313A468BDEAF
  )

  reward_distributed = State.get("reward_distributed", 0)
  State.set("reward_distributed", reward_distributed + user_deposit.reward_amount)

  State.set("rewards_reserved", rewards_reserved - user_deposit.reward_amount)

  reward_token_balance = State.get("reward_token_balance")
  State.set("reward_token_balance", reward_token_balance - user_deposit.reward_amount)

  lp_token_deposited = State.get("lp_token_deposited")
  State.set("lp_token_deposited", lp_token_deposited - amount)

  if amount == user_deposit.amount do
    deposits = Map.delete(deposits, user_genesis_address)
  else
    new_deposit = Map.set(user_deposit, "reward_amount", 0)
    new_deposit = Map.set(new_deposit, "amount", user_deposit.amount - amount)
    deposits = Map.set(deposits, user_genesis_address, new_deposit)
  end

  State.set("deposits", deposits)
end

condition triggered_by: transaction, on: update_code(), as: [
  previous_public_key: (
    # Pool code can only be updated from the router contract of the dex

    # Transaction is not yet validated so we need to use previous address
    # to get the genesis address
    previous_address = Chain.get_previous_address()
    Chain.get_genesis_address(previous_address) == 0x000066CD867DA536A73D39CF05174387923358DC0009A29CC7162D4AED00675DAB55
  )
]

actions triggered_by: transaction, on: update_code() do
  params = [
    0x00006394EF24DFDC6FDFC3642FDC83827591A485704BB997221C0B9F313A468BDEAF,
    1706720400,
    1710763200,
    "UCO",
    0x0000208a670b5590939174d65f88140c05dddba63c0c920582e12162b22f3985e510
  ]

  new_code = Contract.call_function(0x000086E60124C986EBCAA5AFFB7A3DB8213072A132233FE61CF45651FDCF3C4CECEA, "get_farm_code", params)

  if Code.is_valid?(new_code) && !Code.is_same?(new_code, contract.code) do
    Contract.set_type("contract")
    Contract.set_code(new_code)
  end
end

fun get_reward_token_balance() do
  if "UCO" == "UCO" do
    Chain.get_uco_balance(contract.address)
  else
    Chain.get_token_balance(contract.address, "UCO")
  end
end

fun get_user_transfer_amount(tx) do
  transfers = Map.get(transaction.token_transfers, 0x0000208a670b5590939174d65f88140c05dddba63c0c920582e12162b22f3985e510, [])
  transfer = List.at(transfers, 0)

  if transfer != nil && transfer.token_address == 0x00006394EF24DFDC6FDFC3642FDC83827591A485704BB997221C0B9F313A468BDEAF do
    transfer.amount
  else
    0
  end
end

fun calculate_new_rewards() do
  deposits = State.get("deposits", Map.new())
  lp_token_deposited = State.get("lp_token_deposited", 0)
  rewards_reserved = State.get("rewards_reserved", 0)
  last_calculation_timestamp = State.get("last_calculation_timestamp", 1706720400)

  now = Time.now()

  if last_calculation_timestamp < now && last_calculation_timestamp < 1710763200 && lp_token_deposited > 0 do
    rewards_balance = State.get("reward_token_balance", 0)

    available_balance = rewards_balance - rewards_reserved

    amount_to_allocate = 0
    if now >= 1710763200 do
      amount_to_allocate = available_balance
    else
      time_elapsed = now - last_calculation_timestamp
      time_remaining = 1710763200 - last_calculation_timestamp

      amount_to_allocate = available_balance * (time_elapsed / time_remaining)
    end

    if amount_to_allocate > 0 do
      for address in Map.keys(deposits) do
        deposit = Map.get(deposits, address)
        new_reward_amount = amount_to_allocate * (deposit.amount / lp_token_deposited)

        if new_reward_amount > 0 do
          deposit = Map.set(deposit, "reward_amount", deposit.reward_amount + new_reward_amount)
          deposits = Map.set(deposits, address, deposit)

          rewards_reserved = rewards_reserved + new_reward_amount
          last_calculation_timestamp = now
        end
      end
    end
  end

  [
    deposits: deposits,
    rewards_reserved: rewards_reserved,
    last_calculation_timestamp: last_calculation_timestamp
  ]
end

export fun get_farm_infos() do
  reward_token_balance = State.get("reward_token_balance")
  remaining_reward = nil
  if reward_token_balance != nil do
    remaining_reward = reward_token_balance - State.get("rewards_reserved", 0)
  end

  [
    lp_token_address: 0x00006394EF24DFDC6FDFC3642FDC83827591A485704BB997221C0B9F313A468BDEAF,
    reward_token: "UCO",
    start_date: 1706720400,
    end_date: 1710763200,
    remaining_reward: remaining_reward,
    lp_token_deposited: State.get("lp_token_deposited", 0),
    nb_deposit: Map.size(State.get("deposits", Map.new())),
    stats: [
      reward_distributed: State.get("reward_distributed", 0)
    ]
  ]
end

export fun get_user_infos(user_genesis_address) do
  user_genesis_address = String.to_hex(user_genesis_address)

  deposits = State.get("deposits", Map.new())
  user_deposit = Map.get(deposits, user_genesis_address)

  if user_deposit != nil do
    lp_token_deposited = State.get("lp_token_deposited", 0)
    last_calculation_timestamp = State.get("last_calculation_timestamp", 1706720400)

    now = Time.now()

    if now > 1706720400 && last_calculation_timestamp < now && last_calculation_timestamp < 1710763200 && lp_token_deposited > 0 do
      rewards_balance = State.get("reward_token_balance", 0)
      rewards_reserved = State.get("rewards_reserved", 0)

      available_balance = rewards_balance - rewards_reserved

      amount_to_allocate = 0
      if now >= 1710763200 do
        amount_to_allocate = available_balance
      else
        time_elapsed = now - last_calculation_timestamp
        time_remaining = 1710763200 - last_calculation_timestamp

        amount_to_allocate = available_balance * (time_elapsed / time_remaining)
      end

      if amount_to_allocate > 0 do
        new_reward_amount = amount_to_allocate * (user_deposit.amount / lp_token_deposited)

        if new_reward_amount > 0 do
          user_deposit = Map.set(user_deposit, "reward_amount", user_deposit.reward_amount + new_reward_amount)
        end
      end
    end
    [deposited_amount: user_deposit.amount, reward_amount: user_deposit.reward_amount]
  else
    [deposited_amount: 0, reward_amount: 0]
  end
end

Content (0 B)

State (836 B)

{
  "deposits": {
    "000024EFC168359BBE0ABF897270CBFABBFF5784622EA02A463BA2EAF7C5219EAFD7": {
      "amount": 177.66460711,
      "reward_amount": 1006.41626994
    },
    "0000575841F2E8000E8A96C4A523F8D937217ABEB654C12E58C0251300235FCD106F": {
      "amount": 0.55110038,
      "reward_amount": 0.64439923
    },
    "0000834AD179A291856494A6ECA9AA855AAE0F28E5F221666CBD11D2FF96B2A0FE19": {
      "amount": 100.0,
      "reward_amount": 1129.2414009
    },
    "0000A487AD42A5AA666E2021057C89AB92C97513B31EE65DCA76132BEDE148B12843": {
      "amount": 6.05196716,
      "reward_amount": 0
    },
    "0000D9E7B4300CC29670CA80010FE23292BEE4AE28057328732A0FF4CF11C319D81A": {
      "amount": 15.37539248,
      "reward_amount": 58.02410184
    },
    "0000EF25F9910BCF681F5F931F265B4FDD4B2A1FC3469BF20CCE64CDD12CFC2BB57B": {
      "amount": 1.08087472,
      "reward_amount": 4.77894857
    }
  },
  "last_calculation_timestamp": 1706729758,
  "lp_token_deposited": 300.72394185,
  "reward_distributed": 115.60118999,
  "reward_token_balance": 999884.40106863,
  "rewards_reserved": 2199.10512048
}
                  
Movements (0)

Ownerships (1)

  • Secret shared with 1 key

    Encoded secret

    4F9468136ECB4F3EC9384E261870A2590B41822696091A871BF3C2BB968C4ABDB77C50B814E991EF6A67D9E28949D08AD8CB7B35E97A2ADFFE451303

    Authorized keys

    • 00017877BCF4122095926A49489009649603AB129822A19EF9D573B8FD714911ED7F

Contract recipients (0)

Inputs (0)

Contract inputs (0)

Proofs and signatures

Previous public key

0001A59EF42BF82E1493F850BCE421E7F607F3FA2714AA466F33B5D6E6F56E74A5CE

Previous signature

D79597A74A20252AD7472E90D3F64025417A086BFC76DA56D52D7BEE6A77F40158E3FF5FE6205A94BA94A43C5059BA4670F494FC81FB7257E59527D963747E0E

Origin signature

3046022100A2F04016F2EE12EF081C3B05AFCD2D2A17061FD454E0D1527DA53D60E16283FA022100E116DFF61527A968B910A5BF194E6241F6A1DF3EBB256DEB8C93AB91103FB674

Proof of work

010204892A04DBE05192BCB662689E7E19700F3F7202028EF0A9F20635C4948436ED85A43BA3017281EE97781342DD8F24ED6F583B5FE542830FDB5191A11843A72A61

Proof of integrity

0013E538725A59729573DC845995D9FEA7F5BB56E22EA80094E7EC28FDEDE32FAC

Coordinator signature

0428A4C40EA368007AE811D4E97BA976AE01F172D719C8BFFBD2E6CB1A06ABA32C4AEEDD4EE32E6426F1478D5B6A8C223F48D8319B53531BBA3B43E6ACA5BE05

Validator #1 public key

0001500FBE298B79FFBDD5CCA1798F30FD88A53D26EC39DE5DDE1F4137B032A4BC34

Validator #1 signature

9BDB67F902ACA279FCB5CF09A33B4067596111AC61AD6F4064794C237596F7DE745071B0DAC20C17C7DB7200A8720D27268AB7BCB675AD7A9F87BD2DE3969C0A

Validator #2 public key

00011ED0B570D680BE5ECD58D2D121689DA73C46DCB38A01C6E10D06286040ADE30A

Validator #2 signature

21828FC313C234B7BB0D48D31DE0ABE9CB41523C9D28C6B8A39029B255B8032877299B8258265E1C2E9CAB399106805432AD9F980C55F03D0771D43294B3DC04