Msg/Take

Credits can be taken from a basket:

  • message validations
  • when the basket exists
  • when the user token balance is greater than or equal to the token amount
  • when auto-retire is disabled and the user sets retire on take to true
  • when auto-retire is disabled and the user sets retire on take to false
  • when auto-retire is enabled and the user sets retire on take to true
  • the user token balance is updated
  • the basket token supply is updated
  • the user retired credit balance is updated when the user sets retire on take to false
  • the user tradable credit balance is updated when the user sets retire on take to true
  • the basket credit balance is updated
  • the response includes the credits received

Message validations

a valid message

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "100",
  "retirement_jurisdiction": "US-WA",
  "retire_on_take": true,
  "retirement_reason": "offsetting electricity consumption"
}

When the message is validated

Then expect no error.

a valid message without retirement reason

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "100",
  "retirement_jurisdiction": "US-WA",
  "retire_on_take": true
}

When the message is validated

Then expect no error.

a valid message without retire on take

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "100"
}

When the message is validated

Then expect no error.

an error is returned if basket denom is empty

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw"
}

When the message is validated

Then expect the error "basket denom: empty string is not allowed: parse error: invalid request".

an error is returned if basket denom is not formatted

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "foo"
}

When the message is validated

Then expect the error "basket denom: expected format eco.[exponent-prefix][credit-type-abbrev].[name]: parse error: invalid request".

an error is returned if amount is empty

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT"
}

When the message is validated

Then expect the error "amount cannot be empty: invalid request".

an error is returned if a amount is not an integer

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "100.5"
}

When the message is validated

Then expect the error "100.5 is not a valid integer: invalid request".

an error is returned if a amount is less than zero

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "-100"
}

When the message is validated

Then expect the error "amount must be positive, got -100: invalid request".

an error is returned if retirement jurisdiction is empty and retire on take is true

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "100",
  "retire_on_take": true
}

When the message is validated

Then expect the error "retirement jurisdiction cannot be empty if retire on take is true: invalid request".

an error is returned if retirement jurisdiction is not formatted and retire on take is true

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "100",
  "retirement_jurisdiction": "foo",
  "retire_on_take": true
}

When the message is validated

Then expect the error "retirement jurisdiction: expected format [country-code][-[region-code][ [postal-code]]]: parse error: invalid request".

no error is returned if retirement jurisdiction is not formatted and retire on take is false

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "100",
  "retirement_jurisdiction": "foo",
  "retire_on_take": false
}

When the message is validated

Then expect no error.

an error is returned if retirement reason exceeds 512 characters

Given the message

{
  "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw",
  "basket_denom": "eco.uC.NCT",
  "amount": "100",
  "retirement_jurisdiction": "US-WA",
  "retire_on_take": true
}

And retirement reason with length "513"

When the message is validated

Then expect the error "retirement reason: max length 512: limit exceeded".

The basket must exist

Background

Given a credit type with abbreviation "C" and precision "0".

basket exists

Given a basket with denom "eco.uC.NCT"

And alice owns tokens with denom "eco.uC.NCT"

When alice attempts to take credits with basket denom "eco.uC.NCT"

Then expect no error.

basket does not exist

When alice attempts to take credits with basket denom "eco.uC.NCT"

Then expect the error "basket eco.uC.NCT not found: not found".

The user token balance must be greater than or equal to the token amount

Background

Given a credit type with abbreviation "C" and precision "6"

And a basket.

user token balance is greater than or equal to token amount

Given alice owns basket token amount "[token-balance]"

When alice attempts to take credits with basket token amount "[token-amount]"

Then expect no error.

Examples

descriptiontoken-balancetoken-amount
balance greater10050
balance equal100100

user token balance is less than token amount

Given alice owns basket token amount "[token-balance]"

When alice attempts to take credits with basket token amount "[token-amount]"

Then expect the error "insufficient balance for basket denom eco.uC.NCT: insufficient funds".

Examples

descriptiontoken-balancetoken-amount
no balance0100
balance less50100

The user must set retire on take to true if auto-retire is enabled

Background

Given a credit type.

basket auto-retire disabled

Given a basket with disable auto retire "true"

And alice owns basket tokens

When alice attempts to take credits with retire on take "[retire-on-take]"

Then expect no error.

Examples

retire-on-take
true
false

basket auto-retire enabled and user sets retire on take to true

Given a basket with disable auto retire "false"

And alice owns basket tokens

When alice attempts to take credits with retire on take "true"

Then expect no error.

basket auto-retire enabled and user sets retire on take to false

Given a basket with disable auto retire "false"

And alice owns basket tokens

When alice attempts to take credits with retire on take "false"

Then expect the error "can't disable retirement when taking from this basket".

The user token balance is updated when credits are taken from the basket

user token balance is updated

Given a credit type

And a basket

And alice owns basket token amount "100"

When alice attempts to take credits with basket token amount "50"

Then expect alice basket token balance amount "50".

The basket token supply is updated when credits are taken from the basket

basket token supply is updated

Given a credit type

And a basket

And basket token supply amount "100"

And alice owns basket token amount "100"

When alice attempts to take credits with basket token amount "50"

Then expect basket token supply amount "50".

The user credit balance is updated when credits are taken from the basket

user retired credit balance is updated

Given a credit type with abbreviation "C" and precision "[precision]"

And a basket with credit type "C" and disable auto retire "false"

And basket token supply amount "[token-amount]"

And alice owns basket token amount "[token-amount]"

When alice attempts to take credits with basket token amount "[token-amount]" and retire on take "true"

Then expect alice retired credit balance amount "[retired-credits]"

And expect alice tradable credit balance amount "0".

Examples

descriptionprecisiontoken-amountretired-credits
precision zero, credits whole022
precision non-zero, credits whole620000002.000000
precision non-zero, credits decimal625000002.500000

user tradable credit balance is updated

Given a credit type with abbreviation "C" and precision "[precision]"

And a basket with credit type "C" and disable auto retire "true"

And basket token supply amount "[token-amount]"

And alice owns basket token amount "[token-amount]"

When alice attempts to take credits with basket token amount "[token-amount]" and retire on take "false"

Then expect alice tradable credit balance amount "[tradable-credits]"

And expect alice retired credit balance amount "0".

Examples

descriptionprecisiontoken-amounttradable-credits
precision zero, credits whole022
precision non-zero, credits whole620000002.000000
precision non-zero, credits decimal625000002.500000

The basket credit balance is updated when credits are taken from the basket

basket credit balance is updated

Given a credit type with abbreviation "C" and precision "[precision]"

And a basket with credit type "C" and credit balance "100"

And basket token supply amount "[token-amount]"

And alice owns basket token amount "[token-amount]"

When alice attempts to take credits with basket token amount "[token-amount]"

Then expect basket credit balance amount "[credit-amount]".

Examples

descriptionprecisiontoken-amountcredit-amount
precision zero, credits whole0298
precision non-zero, credits whole6200000098.000000
precision non-zero, credits decimal6250000097.500000

The message response includes the credits received when credits are taken from the basket

message response includes basket token amount received

Given a credit type with abbreviation "C" and precision "[precision]"

And a basket with credit type "C" and credit balance "100"

And basket token supply amount "[token-amount]"

And alice owns basket token amount "[token-amount]"

When alice attempts to take credits with basket token amount "[token-amount]"

Then expect the response

{
  "credits": [
    {
      "batch_denom": "C01-001-20200101-20210101-001",
      "amount": "[credit-amount]"
    }
  ]
}

Examples

descriptionprecisiontoken-amountcredit-amount
precision zero, credits whole022
precision non-zero, credits whole620000002.000000
precision non-zero, credits decimal625000002.500000

Events are emitted

Background

Given a credit type with abbreviation "C" and precision "6"

And a basket with credit type "C" and disable auto retire "true"

And basket token supply amount "2000000"

And Alice's address "regen10z82e5ztmrm4pujgummvmr7aqjzwlp6gz8k8xp"

And Ecocredit module's address "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6"

And Alice owns basket token amount "2000000".

EventTake is emitted

When alice attempts to take credits with basket token amount "2000000"

Then expect event take with properties

{
  "owner": "regen10z82e5ztmrm4pujgummvmr7aqjzwlp6gz8k8xp",
  "basket_denom": "eco.uC.NCT",
  "credits": [
    {"batch_denom": "C01-001-20200101-20210101-001", "amount": "2.000000"}
  ],
  "amount": "2000000"
}

EventRetire is emitted

When alice attempts to take credits with basket token amount "2000000" and retire on take "true" from "US-WA" and reason "offsetting electricity consumption"

Then expect event retire with properties

{
  "owner": "regen10z82e5ztmrm4pujgummvmr7aqjzwlp6gz8k8xp",
  "batch_denom": "C01-001-20200101-20210101-001",
  "amount": "2.000000",
  "jurisdiction": "US-WA",
  "reason": "offsetting electricity consumption"
}

EventTransfer is emitted when retire on take is true

When alice attempts to take credits with basket token amount "2000000" and retire on take "true" from "US-WA"

Then expect event transfer with properties

{
  "sender": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6",
  "recipient": "regen10z82e5ztmrm4pujgummvmr7aqjzwlp6gz8k8xp",
  "batch_denom": "C01-001-20200101-20210101-001",
  "retired_amount": "2.000000"
}

EventTransfer is emitted when retire on take is false

When alice attempts to take credits with basket token amount "2000000" and retire on take "false"

Then expect event transfer with properties

{
  "sender": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6",
  "recipient": "regen10z82e5ztmrm4pujgummvmr7aqjzwlp6gz8k8xp",
  "batch_denom": "C01-001-20200101-20210101-001",
  "tradable_amount": "2.000000"
}