diff --git a/PokemonFactory.sol b/PokemonFactory.sol
deleted file mode 100644
index a3267da1..00000000
--- a/PokemonFactory.sol
+++ /dev/null
@@ -1,35 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-
-pragma solidity >=0.7.0 <0.9.0;
-
-contract PokemonFactory {
-
- struct Pokemon {
- uint id;
- string name;
- }
-
- Pokemon[] private pokemons;
-
- mapping (uint => address) public pokemonToOwner;
- mapping (address => uint) ownerPokemonCount;
-
- function createPokemon (string memory _name, uint _id) public {
- pokemons.push(Pokemon(_id, _name));
- pokemonToOwner[_id] = msg.sender;
- ownerPokemonCount[msg.sender]++;
- }
-
- function getAllPokemons() public view returns (Pokemon[] memory) {
- return pokemons;
- }
-
-
- function getResult() public pure returns(uint product, uint sum){
- uint a = 1;
- uint b = 2;
- product = a * b;
- sum = a + b;
- }
-
-}
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..aa3dc221
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+
Pokemon Factory
+
+
+ - Add your Pokemon with a name, id, abilities and types with createPokemon function
+ - You can see the Pokemon List with getAll Pokemon function
+ - You can see weaknesses of a Pokemon from the List with getWeaknesses Pokemon function
+ - You can see the owner of a Pokemon with pokemonToOwner
+
+
+See the contract in Rinkeby 0x1AfFec6C3F0f51ce735835BAa63382f9F5Fe0988
+
+Have fun and catch 'em all!
+
diff --git a/contracts/PokemonFactory.sol b/contracts/PokemonFactory.sol
new file mode 100644
index 00000000..4dae2169
--- /dev/null
+++ b/contracts/PokemonFactory.sol
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-3.0
+
+pragma solidity >=0.7.0 <0.9.0;
+
+import "./StringUtils.sol";
+import "./TypesUtils.sol";
+
+contract PokemonFactory {
+
+ struct Pokemon {
+ uint id;
+ string name;
+ Type[] typesList;
+ Ability[] abilities;
+ }
+
+ struct Ability {
+ string name;
+ string description;
+ }
+
+ struct Type {
+ Types id;
+ string name;
+ }
+
+ enum Types{
+ Normal,
+ Fighting,
+ Flying,
+ Poison,
+ Ground,
+ Rock,
+ Bug,
+ Ghost,
+ Steel,
+ Fire,
+ Water,
+ Grass,
+ Electric,
+ Psychic,
+ Ice,
+ Dragon,
+ Fairy,
+ Dark
+ }
+
+ Pokemon[] private pokemons;
+ mapping (address => uint) ownerPokemonCount;
+ mapping (uint => address) public pokemonToOwner;
+
+ event eventNewPokemon(string name, uint id);
+
+ modifier validateEntries(string memory _name, uint _id, Ability[] memory _abilities, Types[] memory _type) {
+ require(_id != 0, "Id must be greater than 0");
+ require(StringUtils.strlen(_name) > 2, "Name must have more than 2 characters");
+ require(_abilities.length > 0 && _abilities.length < 4, "Must have between 1 to 3 Abilities");
+ require(_type.length > 0 && _type.length < 3, "Must have 1 or 2 Types");
+
+ for (uint i = 0; i < _abilities.length; i++) {
+ for (uint j = 1; j <_abilities.length; j++) {
+ if(j != i && keccak256(abi.encodePacked((_abilities[i].name))) == keccak256(abi.encodePacked((_abilities[j].name)))){
+ revert("You have duplicated Abilities");
+ }
+ }
+ }
+
+ for (uint i = 0; i < _type.length; i++) {
+ for (uint j = 1; j <_type.length; j++) {
+ if(j != i && _type[i] == _type[j]){
+ revert("You have duplicated Types");
+ }
+ }
+ }
+ _;
+ }
+
+ /**
+ * @dev create a pokemon
+ *
+ * @param _name Name of the Pokemon
+ * @param _id id of the Pokemon
+ * @param _abilities Abilities of the Pokemon
+ * @param _type Type of Pokemon
+ */
+ function createPokemon (string memory _name, uint _id, Ability[] memory _abilities, Types[] memory _type) public validateEntries(_name, _id, _abilities, _type){
+ //create first pokemon struct in pokemons
+ Pokemon storage pokemon = pokemons.push();
+ pokemon.id = _id;
+ pokemon.name = _name;
+ for (uint i = 0; i <_abilities.length; i++) {
+ pokemon.abilities.push(Ability(_abilities[i].name, _abilities[i].description));
+ }
+ for (uint i = 0; i <_type.length; i++) {
+ pokemon.typesList.push(Type(_type[i], TypesUtils.typeName(uint8(_type[i]))));
+ }
+ pokemonToOwner[_id] = msg.sender;
+ ownerPokemonCount[msg.sender]++;
+ emit eventNewPokemon(_name, _id);
+ }
+
+ /**
+ * @dev get weaknesses of a Pokemon
+ *
+ * @param _pokemonIndex index of pokemons array
+ * @return array of weaknesses
+ */
+ function getWeaknesses (uint _pokemonIndex) public view returns (string[] memory) {
+ Pokemon memory pokemon = pokemons[_pokemonIndex];
+ string[] memory weaknesses = new string[](pokemon.typesList.length);
+ for (uint i = 0; i < pokemon.typesList.length; i++) {
+ weaknesses[i] = TypesUtils.Weakness(uint8(pokemon.typesList[i].id));
+ }
+ return weaknesses;
+ }
+
+ /**
+ * @dev get all Pokemons of pokemons array
+ * @return array pokemons
+ */
+ function getAllPokemons() public view returns (Pokemon[] memory) {
+ return pokemons;
+ }
+}
diff --git a/contracts/StringUtils.sol b/contracts/StringUtils.sol
new file mode 100644
index 00000000..9ae702c3
--- /dev/null
+++ b/contracts/StringUtils.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: MIT
+// Source:
+// https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/StringUtils.sol
+pragma solidity >=0.7.0 <0.9.0;
+
+library StringUtils {
+ /**
+ * @dev Returns the length of a given string
+ *
+ * @param s The string to measure the length of
+ * @return The length of the input string
+ */
+ function strlen(string memory s) internal pure returns (uint) {
+ uint len;
+ uint i = 0;
+ uint bytelength = bytes(s).length;
+ for(len = 0; i < bytelength; len++) {
+ bytes1 b = bytes(s)[i];
+ if(b < 0x80) {
+ i += 1;
+ } else if (b < 0xE0) {
+ i += 2;
+ } else if (b < 0xF0) {
+ i += 3;
+ } else if (b < 0xF8) {
+ i += 4;
+ } else if (b < 0xFC) {
+ i += 5;
+ } else {
+ i += 6;
+ }
+ }
+ return len;
+ }
+}
\ No newline at end of file
diff --git a/contracts/TypesUtils.sol b/contracts/TypesUtils.sol
new file mode 100644
index 00000000..e706fa75
--- /dev/null
+++ b/contracts/TypesUtils.sol
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity >=0.7.0 <0.9.0;
+
+library TypesUtils {
+
+ /**
+ * @dev Returns Name
+ *
+ * @param id Type of pokemon
+ * @return string Name
+ */
+ function typeName(uint8 id) internal pure returns (string memory){
+ if (id == 0) {
+ return "Normal";
+ } else if (id == 1) {
+ return "Fighting";
+ } else if (id == 2) {
+ return "Flying";
+ } else if (id == 3) {
+ return "Poison";
+ } else if (id == 4) {
+ return "Ground";
+ } else if (id == 5) {
+ return "Rock";
+ } else if (id == 6) {
+ return "Bug";
+ } else if (id == 7) {
+ return "Ghost";
+ } else if (id == 8) {
+ return "Steel";
+ } else if (id == 9) {
+ return "Fire";
+ } else if (id == 10) {
+ return "Water";
+ } else if (id == 11) {
+ return "Grass";
+ } else if (id == 12) {
+ return "Electric";
+ } else if (id == 13) {
+ return "Psychic";
+ } else if (id == 14) {
+ return "Ice";
+ } else if (id == 15) {
+ return "Dragon";
+ } else if (id == 16) {
+ return "Fairy";
+ } else {
+ return "Dark";
+ }
+ }
+
+ /**
+ * @dev Returns string of weaknesses per type
+ *
+ * @param id Type of pokemon
+ * @return string of weaknesses
+ */
+ function Weakness(uint8 id) internal pure returns (string memory) {
+ if (id == 0) {
+ return "Rock, Ghost, Steel";
+ } else if (id == 1) {
+ return "Flying, Poison, Psychic, Bug, Ghost, Fairy";
+ } else if (id == 2) {
+ return "Rock, Steel, Electric";
+ } else if (id == 3) {
+ return "Poison, Ground, Rock, Ghost, Steel";
+ } else if (id == 4) {
+ return "Flying, Bug, Grass";
+ } else if (id == 5) {
+ return "Fighting, Ground, Steel";
+ } else if (id == 6) {
+ return "Fighting, Flying, Poison, Ghost, Steel, Fire, Fairy";
+ } else if (id == 7) {
+ return "Normal, Dark";
+ } else if (id == 8) {
+ return "Steel, Fire, Water, Electric";
+ } else if (id == 9) {
+ return "Rock, Fire, Water, Dragon";
+ } else if (id == 10) {
+ return "Water, Grass, Dragon";
+ } else if (id == 11) {
+ return "Flying, Poison, Bug, Steel, Fire, Grass, Dragon";
+ } else if (id == 12) {
+ return "Flying, Steel, Electric";
+ } else if (id == 13) {
+ return "Steel, Psychic, Dark";
+ } else if (id == 14) {
+ return "Steel, Fire, Water, Ice";
+ } else if (id == 15) {
+ return "Steel, Fairy";
+ } else if (id == 16) {
+ return "Poison, Steel, Fire";
+ } else {
+ return "Fighting, Dark, Fairy";
+ }
+ }
+}
\ No newline at end of file